From 8896a40efcf065d9716f78a67f59f292d1e6171f Mon Sep 17 00:00:00 2001 From: Ray <113240139+Ray-Not@users.noreply.github.com> Date: Tue, 9 May 2023 23:29:13 +0300 Subject: [PATCH 01/61] Update .gitignore --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 862eb15..d285d5b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ # BlueJ files *.ctxt - +# # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -23,4 +23,4 @@ hs_err_pid* # idea -.idea \ No newline at end of file +.idea From 1ac519932412281f7fa53d1b89db0a16df605ec2 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Mon, 15 May 2023 14:23:34 +0500 Subject: [PATCH 02/61] Add hw8 --- FP/.github/workflows/bot.yml | 75 ++++++ FP/.github/workflows/scrapper.yml | 74 ++++++ FP/FP/.project | 18 ++ FP/FP/bot/.classpath | 34 +++ .../bot/.dbeaver/.credentials-config.json.bak | Bin 0 -> 112 bytes FP/FP/bot/.dbeaver/.data-sources.json.bak | 4 + FP/FP/bot/.dbeaver/.project-metadata.json.bak | 1 + FP/FP/bot/.dbeaver/data-sources.json | 6 + FP/FP/bot/.dbeaver/project-metadata.json | 1 + FP/FP/bot/.dbeaver/project-settings.json | 1 + FP/FP/bot/.gitignore | 1 + FP/FP/bot/.project | 24 ++ .../org.eclipse.core.resources.prefs | 6 + .../bot/.settings/org.eclipse.jdt.core.prefs | 9 + .../bot/.settings/org.eclipse.m2e.core.prefs | 4 + FP/FP/bot/pom.xml | 110 ++++++++ .../tinkoff/edu/java/bot/BotApplication.java | 16 ++ .../java/bot/advice/AppExceptionHandler.java | 28 ++ .../edu/java/bot/client/ScrapperClient.java | 103 +++++++ .../bot/client/ScrapperClientException.java | 11 + .../edu/java/bot/commands/Command.java | 20 ++ .../edu/java/bot/commands/CommandsEnum.java | 33 +++ .../edu/java/bot/commands/HelpCommand.java | 23 ++ .../edu/java/bot/commands/ListCommand.java | 48 ++++ .../edu/java/bot/commands/StartCommand.java | 55 ++++ .../edu/java/bot/commands/TrackCommand.java | 47 ++++ .../edu/java/bot/commands/UntrackCommand.java | 49 ++++ .../bot/configuration/ApplicationConfig.java | 12 + .../bot/configuration/BotConfiguration.java | 78 ++++++ .../configuration/ClientConfiguration.java | 27 ++ .../LinkParserConfiguration.java | 15 ++ .../configuration/RabbitMQConfiguration.java | 77 ++++++ .../edu/java/bot/dto/AddLinkRequest.java | 6 + .../edu/java/bot/dto/ApiErrorResponse.java | 7 + .../tinkoff/edu/java/bot/dto/BotCommand.java | 8 + .../ru/tinkoff/edu/java/bot/dto/Link.java | 10 + .../edu/java/bot/dto/LinkResponse.java | 11 + .../tinkoff/edu/java/bot/dto/LinkUpdate.java | 5 + .../edu/java/bot/dto/ListLinkResponse.java | 6 + .../edu/java/bot/dto/RemoveLinkRequest.java | 5 + .../edu/java/bot/dto/SetCommandRequest.java | 7 + .../tinkoff/edu/java/bot/dto/UserAddDto.java | 8 + .../bot/exceptions/ChatNotFoundException.java | 10 + .../LinkIsNotRegisteredToChatException.java | 10 + .../edu/java/bot/rest/BotRestController.java | 29 ++ .../bot/service/ScrapperQueueListener.java | 29 ++ .../edu/java/bot/service/UpdateService.java | 8 + .../java/bot/service/UpdateServiceImpl.java | 26 ++ .../ru/tinkoff/edu/java/bot/telegram/Bot.java | 52 ++++ .../bot/telegram/UserMessageProcessor.java | 126 +++++++++ .../edu/java/bot/telegram/UserState.java | 5 + .../src/main/resources/application.properties | 14 + FP/FP/bot/src/test/java/bot/BotTest.java | 123 +++++++++ FP/FP/docker-compose.yml | 60 +++++ FP/FP/link-parser/.classpath | 41 +++ FP/FP/link-parser/.gitignore | 1 + FP/FP/link-parser/.project | 23 ++ .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.core.prefs | 9 + .../.settings/org.eclipse.m2e.core.prefs | 4 + FP/FP/link-parser/pom.xml | 30 +++ .../java/link_parser/link/GitHub_Link.java | 5 + .../java/link_parser/link/Parser_Link.java | 5 + .../link_parser/link/StackOverflow_Link.java | 5 + .../edu/java/link_parser/parser/Abstract.java | 27 ++ .../edu/java/link_parser/parser/Github.java | 31 +++ .../java/link_parser/parser/Link_Parser.java | 16 ++ .../link_parser/parser/StackOverflow.java | 34 +++ .../src/test/java/LinkParserTest.java | 99 +++++++ FP/FP/migrations/01-schema-1.sql | 11 + FP/FP/migrations/02-schema-2.sql | 15 ++ FP/FP/migrations/03-schema-3.sql | 10 + FP/FP/migrations/create.sql | 18 ++ FP/FP/migrations/delete.sql | 3 + FP/FP/migrations/insert.sql | 37 +++ FP/FP/migrations/master.xml | 13 + FP/FP/pom.xml | 123 +++++++++ FP/FP/scrapper-jooq/.classpath | 28 ++ FP/FP/scrapper-jooq/.gitignore | 1 + FP/FP/scrapper-jooq/.project | 23 ++ .../org.eclipse.core.resources.prefs | 4 + .../.settings/org.eclipse.jdt.core.prefs | 9 + .../.settings/org.eclipse.m2e.core.prefs | 4 + FP/FP/scrapper-jooq/pom.xml | 40 +++ .../src/main/java/JooqCodegen.java | 54 ++++ FP/FP/scrapper/.classpath | 41 +++ FP/FP/scrapper/.gitignore | 1 + FP/FP/scrapper/.project | 23 ++ .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.core.prefs | 9 + .../.settings/org.eclipse.m2e.core.prefs | 4 + FP/FP/scrapper/pom.xml | 120 +++++++++ .../java/scrapper/ScrapperApplication.java | 22 ++ .../scrapper/advice/AppExceptionHandler.java | 33 +++ .../edu/java/scrapper/client/BotClient.java | 38 +++ .../java/scrapper/client/GitHubClient.java | 47 ++++ .../scrapper/client/StackOverflowClient.java | 44 +++ .../configuration/ApplicationConfig.java | 26 ++ .../configuration/ClientConfiguration.java | 44 +++ .../configuration/HTTPConfiguration.java | 28 ++ .../LinkParserConfiguration.java | 14 + .../configuration/RabbitMQConfiguration.java | 50 ++++ .../acess/JdbcAccessConfiguration.java | 99 +++++++ .../acess/JooqAccessConfiguration.java | 84 ++++++ .../acess/JpaAccessConfiguration.java | 61 +++++ .../edu/java/scrapper/dto/AddLinkRequest.java | 5 + .../java/scrapper/dto/ApiErrorResponse.java | 6 + .../edu/java/scrapper/dto/GitHubResponse.java | 25 ++ .../edu/java/scrapper/dto/LinkResponse.java | 5 + .../edu/java/scrapper/dto/LinkUpdate.java | 5 + .../java/scrapper/dto/ListLinkResponse.java | 8 + .../java/scrapper/dto/RemoveLinkRequest.java | 5 + .../java/scrapper/dto/StackOverflowItem.java | 8 + .../scrapper/dto/StackOverflowResponse.java | 8 + .../edu/java/scrapper/dto/UserAddDto.java | 8 + .../BadResponseFromApiException.java | 12 + .../exception/BotClientException.java | 11 + .../exception/ChatAlreadyExistException.java | 11 + .../exception/ChatNotFoundException.java | 12 + .../exception/GitHubRequestException.java | 11 + .../LinkIsAlreadyAddedException.java | 12 + .../exception/LinkNotFoundException.java | 12 + .../StackOverflowRequestException.java | 12 + .../java/scrapper/mapper/LinkRowMapper.java | 27 ++ .../mapper/SubscriptionRowMapper.java | 20 ++ .../java/scrapper/mapper/UserRowMapper.java | 24 ++ .../java/scrapper/model/commonDto/Link.java | 31 +++ .../java/scrapper/model/commonDto/User.java | 32 +++ .../scrapper/model/jdbcAndJooq/Relation.java | 11 + .../java/scrapper/model/jpa/LinkEntity.java | 40 +++ .../java/scrapper/model/jpa/UserEntity.java | 30 +++ .../jdbc/LinkJdbcTemplateRepository.java | 86 ++++++ .../SubscriptionJdbcTemplateRepository.java | 75 ++++++ .../jdbc/UserJdbcTemplateRepository.java | 59 ++++ .../jdbcAndJooqContract/LinkRepository.java | 21 ++ .../SubscriptionRepository.java | 19 ++ .../jdbcAndJooqContract/UserRepository.java | 13 + .../repository/jooq/LinkJooqRepository.java | 98 +++++++ .../jooq/SubscriptionJooqRepository.java | 80 ++++++ .../repository/jooq/UserJooqRepository.java | 59 ++++ .../repository/jpa/JpaLinkRepository.java | 20 ++ .../repository/jpa/JpaUserRepository.java | 22 ++ .../scrapper/rest/ChatRestController.java | 30 +++ .../scrapper/rest/LinkRestController.java | 44 +++ .../schedule/LinkUpdateScheduler.java | 26 ++ .../edu/java/scrapper/schedule/Scheduler.java | 6 + .../service/ScrapperQueueProducer.java | 26 ++ .../service/UpdateNotificationService.java | 8 + .../service/contract/LinkUpdateService.java | 12 + .../service/contract/SubscriptionService.java | 14 + .../service/contract/TgChatService.java | 11 + .../impl/LinkUpdateServiceImpl.java | 156 +++++++++++ .../impl/SubscriptionServiceImpl.java | 99 +++++++ .../jdbcAndJooq/impl/TgChatServiceImpl.java | 42 +++ .../jpa/impl/JpaLinkUpdateServiceImpl.java | 174 ++++++++++++ .../jpa/impl/JpaSubscriptionServiceImpl.java | 100 +++++++ .../jpa/impl/JpaTgChatServiceImpl.java | 43 +++ .../src/main/resources/application.properties | 23 ++ .../src/main/resources/logback-test.xml | 17 ++ .../src/test/java/scrapper/DatabaseTest.java | 38 +++ .../java/scrapper/IntegrationEnvironment.java | 54 ++++ .../scrapper/environment/DatabaseTest.java | 38 +++ .../environment/IntegrationEnvironment.java | 81 ++++++ .../environment/TestConfiguration.java | 8 + .../test/java/scrapper/jdbc/JdbcLinkTest.java | 151 +++++++++++ .../scrapper/jdbc/JdbcSubscriptionTest.java | 251 ++++++++++++++++++ .../test/java/scrapper/jdbc/JdbcUserTest.java | 135 ++++++++++ 167 files changed, 5628 insertions(+) create mode 100644 FP/.github/workflows/bot.yml create mode 100644 FP/.github/workflows/scrapper.yml create mode 100644 FP/FP/.project create mode 100644 FP/FP/bot/.classpath create mode 100644 FP/FP/bot/.dbeaver/.credentials-config.json.bak create mode 100644 FP/FP/bot/.dbeaver/.data-sources.json.bak create mode 100644 FP/FP/bot/.dbeaver/.project-metadata.json.bak create mode 100644 FP/FP/bot/.dbeaver/data-sources.json create mode 100644 FP/FP/bot/.dbeaver/project-metadata.json create mode 100644 FP/FP/bot/.dbeaver/project-settings.json create mode 100644 FP/FP/bot/.gitignore create mode 100644 FP/FP/bot/.project create mode 100644 FP/FP/bot/.settings/org.eclipse.core.resources.prefs create mode 100644 FP/FP/bot/.settings/org.eclipse.jdt.core.prefs create mode 100644 FP/FP/bot/.settings/org.eclipse.m2e.core.prefs create mode 100644 FP/FP/bot/pom.xml create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java create mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java create mode 100644 FP/FP/bot/src/main/resources/application.properties create mode 100644 FP/FP/bot/src/test/java/bot/BotTest.java create mode 100644 FP/FP/docker-compose.yml create mode 100644 FP/FP/link-parser/.classpath create mode 100644 FP/FP/link-parser/.gitignore create mode 100644 FP/FP/link-parser/.project create mode 100644 FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs create mode 100644 FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs create mode 100644 FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs create mode 100644 FP/FP/link-parser/pom.xml create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java create mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java create mode 100644 FP/FP/link-parser/src/test/java/LinkParserTest.java create mode 100644 FP/FP/migrations/01-schema-1.sql create mode 100644 FP/FP/migrations/02-schema-2.sql create mode 100644 FP/FP/migrations/03-schema-3.sql create mode 100644 FP/FP/migrations/create.sql create mode 100644 FP/FP/migrations/delete.sql create mode 100644 FP/FP/migrations/insert.sql create mode 100644 FP/FP/migrations/master.xml create mode 100644 FP/FP/pom.xml create mode 100644 FP/FP/scrapper-jooq/.classpath create mode 100644 FP/FP/scrapper-jooq/.gitignore create mode 100644 FP/FP/scrapper-jooq/.project create mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs create mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs create mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs create mode 100644 FP/FP/scrapper-jooq/pom.xml create mode 100644 FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java create mode 100644 FP/FP/scrapper/.classpath create mode 100644 FP/FP/scrapper/.gitignore create mode 100644 FP/FP/scrapper/.project create mode 100644 FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs create mode 100644 FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs create mode 100644 FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs create mode 100644 FP/FP/scrapper/pom.xml create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java create mode 100644 FP/FP/scrapper/src/main/resources/application.properties create mode 100644 FP/FP/scrapper/src/main/resources/logback-test.xml create mode 100644 FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java create mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java diff --git a/FP/.github/workflows/bot.yml b/FP/.github/workflows/bot.yml new file mode 100644 index 0000000..a693ee2 --- /dev/null +++ b/FP/.github/workflows/bot.yml @@ -0,0 +1,75 @@ +name: Bot Actions +run-name: Bot Pipeline go! πŸš€ +on: + push: + branches: [ "master", "hw9" ] + paths: + - 'app/bot/**' + pull_request: + branches: [ "master", "hw9" ] + paths: + - 'app/bot/**' + +env: + REGISTRY: ghcr.io + +permissions: + packages: write + + +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + + - name: Checkout repository + uses: actions/checkout@v3 + + - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." + + - name: List files in the repository + run: | + ls ${{ github.workspace }} + + - name: Set up Java 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: mvn package -pl bot -am + working-directory: app + + - name: Build Docker image + run: docker build -t ${{ env.REGISTRY }}/${{ github.actor }}/bot-image -f app/bot/Dockerfile . + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Docker image to GH Packages + run: docker push ${{ env.REGISTRY }}/${{ github.actor }}/bot-image + + code-check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Java 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven and check + run: mvn package -pl bot -am checkstyle:check + working-directory: app diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml new file mode 100644 index 0000000..b202d58 --- /dev/null +++ b/FP/.github/workflows/scrapper.yml @@ -0,0 +1,74 @@ +name: Scrapper Actions +run-name: Scrapper Pipeline go! πŸš€ +on: + push: + branches: [ "master", "hw9" ] + paths: + - 'app/scrapper/**' + pull_request: + branches: [ "master", "hw9" ] + paths: + - 'app/scrapper/**' + +env: + REGISTRY: ghcr.io + +permissions: + packages: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + + - name: Checkout repository + uses: actions/checkout@v3 + + - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." + + - name: List files in the repository + run: | + ls -la ${{ github.workspace }} + + - name: Set up Java 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: mvn package -pl scrapper -am + working-directory: app + + - name: Build Docker image + run: docker build -t ${{ env.REGISTRY }}/${{ github.actor }}/scrapper-image -f app/scrapper/Dockerfile . + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Docker image to GH Packages + run: docker push ${{ env.REGISTRY }}/${{ github.actor }}/scrapper-image + + code-check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Java 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven and check + run: mvn package -pl scrapper -am checkstyle:check + working-directory: app diff --git a/FP/FP/.project b/FP/FP/.project new file mode 100644 index 0000000..89d138f --- /dev/null +++ b/FP/FP/.project @@ -0,0 +1,18 @@ + + + project + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.jkiss.dbeaver.DBeaverNature + + diff --git a/FP/FP/bot/.classpath b/FP/FP/bot/.classpath new file mode 100644 index 0000000..0b9fa8d --- /dev/null +++ b/FP/FP/bot/.classpath @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FP/FP/bot/.dbeaver/.credentials-config.json.bak b/FP/FP/bot/.dbeaver/.credentials-config.json.bak new file mode 100644 index 0000000000000000000000000000000000000000..8320c631e208c3ad7467cf2d9db83d85e90f14f8 GIT binary patch literal 112 zcmV-$0FVC>%bw`qlvu4i=Wrho)ja=8tm(6RtT%VUiv(RbXd+9@8O^=>KI816Agz S3>36s#U(-2xgbD9^um4; + + bot + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.jkiss.dbeaver.DBeaverNature + + diff --git a/FP/FP/bot/.settings/org.eclipse.core.resources.prefs b/FP/FP/bot/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/FP/FP/bot/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs b/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..5e4ec05 --- /dev/null +++ b/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs b/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/FP/FP/bot/pom.xml b/FP/FP/bot/pom.xml new file mode 100644 index 0000000..7d7818b --- /dev/null +++ b/FP/FP/bot/pom.xml @@ -0,0 +1,110 @@ + + 4.0.0 + + project + project + 0.0.1-SNAPSHOT + + bot + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework + spring-context-indexer + true + + + org.projectlombok + lombok + true + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.0.2 + + + com.github.pengrad + java-telegram-bot-api + 6.6.0 + + + ru.tinkoff.edu + link-parser + 1.0-SNAPSHOT + + + org.springframework + spring-context + 6.0.3 + + + org.springframework + spring-test + 6.0.6 + test + + + org.junit.jupiter + junit-jupiter-params + + + org.mockito + mockito-core + + + org.springframework.boot + spring-boot-starter-amqp + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + ../checkstyle.xml + + + + + \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java new file mode 100644 index 0000000..50cd2b8 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java @@ -0,0 +1,16 @@ +package ru.tinkoff.edu.java.bot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import ru.tinkoff.edu.java.bot.configuration.ApplicationConfig; + +@SpringBootApplication +@EnableConfigurationProperties(ApplicationConfig.class) +public class BotApplication { + public static void main(String[] args) { + var ctx = SpringApplication.run(BotApplication.class, args); + ApplicationConfig config = ctx.getBean(ApplicationConfig.class); + + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java new file mode 100644 index 0000000..8ff54fd --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java @@ -0,0 +1,28 @@ +package ru.tinkoff.edu.java.bot.advice; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.tinkoff.edu.java.bot.dto.ApiErrorResponse; +import ru.tinkoff.edu.java.bot.exceptions.ChatNotFoundException; +import ru.tinkoff.edu.java.bot.exceptions.LinkIsNotRegisteredToChatException; + +import java.util.Arrays; + +@RestControllerAdvice +public class AppExceptionHandler { + + @ExceptionHandler({LinkIsNotRegisteredToChatException.class, ChatNotFoundException.class}) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public ApiErrorResponse handleNotFoundExceptions(RuntimeException exception) { + return new ApiErrorResponse( + "Error", + HttpStatus.BAD_REQUEST.toString(), + exception.getClass().getName(), + exception.getMessage(), + Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new) + ); + } + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java new file mode 100644 index 0000000..c8b8bab --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java @@ -0,0 +1,103 @@ +package ru.tinkoff.edu.java.bot.client; + +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import ru.tinkoff.edu.java.bot.dto.*; + + +public class ScrapperClient { + + private final WebClient webClient; + + private final String wentWrongMessage = "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° нашСй сторонС, ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ ΠΏΠΎΠ·ΠΆΠ΅"; + + //По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - webClient инТСктится ΠΈΠ· ClientConfiguration c baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ + public ScrapperClient(WebClient webClient) { + this.webClient = webClient; + } + + //Π—Π΄Π΅ΡΡŒ webClient Π½Π΅ инТСктится, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ baseUrl. + public ScrapperClient(String baseUrl) { + this.webClient = WebClient.create(baseUrl); + } + + public ListLinkResponse getLinks(Long tgChatId) { + ListLinkResponse response = + webClient.get().uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)).exchangeToMono(r -> { + if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { + throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); + } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { + throw new ScrapperClientException( + wentWrongMessage); + } + return r.bodyToMono(ListLinkResponse.class); + }).block(); + + return response; + } + + public LinkResponse addLink(Long tgChatId, AddLinkRequest request) { + LinkResponse response = webClient.post().uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)) + .bodyValue(request).exchangeToMono(r -> { + if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { + throw new ScrapperClientException("Бсылка с Ρ‚Π°ΠΊΠΈΠΌ URL ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°"); + } else if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { + throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); + } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { + throw new ScrapperClientException( + wentWrongMessage); + } + return r.bodyToMono(LinkResponse.class); + }).block(); + + return response; + } + + public LinkResponse deleteLink(Long tgChatId, RemoveLinkRequest request) { + LinkResponse response = + webClient.method(HttpMethod.DELETE).uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)) + .bodyValue(request).exchangeToMono(r -> { + if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { + throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½Π° ссылка"); + } else if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { + throw new ScrapperClientException( + "Бсылка с Ρ‚Π°ΠΊΠΈΠΌ URL Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° ΠΈΠ»ΠΈ Ρ‡Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); + } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { + throw new ScrapperClientException( + wentWrongMessage); + } + return r.bodyToMono(LinkResponse.class); + }).block(); + + return response; + } + + public void registerChat(Long tgChatId, UserAddDto userAddDto) { + webClient.post().uri("/tg-chat/{id}", tgChatId).bodyValue(userAddDto).exchangeToMono(response -> { + if (response.statusCode().equals(HttpStatus.BAD_REQUEST)) { + throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½ ID ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ ΡƒΠΆΠ΅ зарСгистрирован"); + } else if (response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { + throw new ScrapperClientException( + wentWrongMessage); + } + return Mono.empty(); + }).block(); + } + + public void deleteChat(Long tgChatId) { + webClient.delete().uri("/tg-chat/{id}", tgChatId).exchangeToMono(response -> { + if (response.statusCode().equals(HttpStatus.BAD_REQUEST)) { + throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½ ID"); + } else if (response.statusCode().equals(HttpStatus.NOT_FOUND)) { + throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½"); + } else if (response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { + throw new ScrapperClientException( + wentWrongMessage); + } + return Mono.empty(); + }).block(); + } + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java new file mode 100644 index 0000000..9ef91d4 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.bot.client; + +public class ScrapperClientException extends RuntimeException{ + + public ScrapperClientException() { + } + + public ScrapperClientException(String message) { + super(message); + } +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java new file mode 100644 index 0000000..a179c88 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import ru.tinkoff.edu.java.bot.dto.BotCommand; + +public interface Command { + String command(); + + String description(); + + String handle(Update update); + + default boolean supports(Update update) { + return update.message().text().equals(command()); + } + + default BotCommand toApiCommand() { + return new BotCommand(command(), description()); + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java new file mode 100644 index 0000000..1d3852c --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java @@ -0,0 +1,33 @@ +package ru.tinkoff.edu.java.bot.commands; + +import java.util.HashMap; +import java.util.Map; + +public enum CommandsEnum { + + START ("/start"), + HELP ("/help"), + LIST ("/list"), + TRACK ("/track"), + UNTRACK ("/untrack"); + + private static final Map BY_LABEL = new HashMap<>(); + + static { + for (CommandsEnum c : values()) { + BY_LABEL.put(c.label, c); + } + } + + private final String label; + + CommandsEnum(String command) { + this.label = command; + } + + public static CommandsEnum valueOfLabel(String label) { + return BY_LABEL.get(label); + } + + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java new file mode 100644 index 0000000..b8e8b62 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java @@ -0,0 +1,23 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.stereotype.Component; + +@Component +public class HelpCommand implements Command{ + @Override + public String command() { + return "/help"; + } + + @Override + public String description() { + return "вывСсти ΠΎΠΊΠ½ΠΎ с ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ"; + } + + @Override + public String handle(Update update) { + return "Help is executing..."; + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java new file mode 100644 index 0000000..6a3176e --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java @@ -0,0 +1,48 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; +import ru.tinkoff.edu.java.bot.client.ScrapperClientException; +import ru.tinkoff.edu.java.bot.dto.Link; +import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; + +@Component +public class ListCommand implements Command { + + private final ScrapperClient scrapperClient; + + public ListCommand(ScrapperClient scrapperClient) { + this.scrapperClient = scrapperClient; + } + + @Override + public String command() { + return "/list"; + } + + @Override + public String description() { + return "ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ список отслСТиваСмых ссылок"; + } + + @Override + public String handle(Update update) { + long chatId = update.message().chat().id(); + try { + ListLinkResponse response = scrapperClient.getLinks(chatId); + StringBuilder msg = new StringBuilder(); + if (response.size() == 0) + msg.append("Бписок отслСТиваСмых ссылок пуст!"); + else { + msg.append("Бсылок отслСТиваСтся - ").append(response.size()).append("\n\n"); + for (Link link : response.links()) { + msg.append(link.url()).append("\n\n"); + } + } + return msg.toString(); + } catch (ScrapperClientException e){ + return e.getMessage(); + } + } +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java new file mode 100644 index 0000000..98da89f --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java @@ -0,0 +1,55 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.model.request.InlineKeyboardButton; +import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; +import ru.tinkoff.edu.java.bot.client.ScrapperClientException; +import ru.tinkoff.edu.java.bot.dto.Link; +import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; +import ru.tinkoff.edu.java.bot.dto.UserAddDto; + +@Component +public class StartCommand implements Command { + + private final ScrapperClient scrapperClient; + + public StartCommand(ScrapperClient scrapperClient) { + this.scrapperClient = scrapperClient; + } + + @Value("${tg.bot.token}") + private String token; + + @Override + public String command() { + return "/start"; + } + + @Override + public String description() { + return "Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ"; + } + + @Override + public String handle(Update update) { + long chatId = update.message().chat().id(); + try { + UserAddDto userAddDto = new UserAddDto(update.message().chat().username(), + update.message().chat().firstName(), + update.message().chat().lastName() + ); + scrapperClient.registerChat(chatId, userAddDto); + return "ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Π Π°Π΄ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ, " + update.message().chat().firstName(); + } catch (ScrapperClientException e) { + + return e.getMessage(); + } + + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java new file mode 100644 index 0000000..fed745d --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java @@ -0,0 +1,47 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; +import ru.tinkoff.edu.java.bot.client.ScrapperClientException; +import ru.tinkoff.edu.java.bot.dto.AddLinkRequest; + +@Component +public class TrackCommand implements Command { + + private final Link_Parser parser; + + public TrackCommand(ScrapperClient scrapperClient, LinkParser parser) { + this.scrapperClient = scrapperClient; + this.parser = parser; + } + + private final ScrapperClient scrapperClient; + + @Override + public String command() { + return "/track"; + } + + @Override + public String description() { + return "Π½Π°Ρ‡Π°Ρ‚ΡŒ отслСТиваниС ссылки"; + } + + @Override + public String handle(Update update) { + long chatId = update.message().chat().id(); + String msg; + try { + if (parser.parseUrl(update.message().text()) != null){ + scrapperClient.addLink(chatId, new AddLinkRequest(update.message().text())); + msg = "Бсылка ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°"; + } else msg = "НСкоррСктная ссылка"; + return msg; + } catch (ScrapperClientException e) { + return e.getMessage(); + } + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java new file mode 100644 index 0000000..df1c58a --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java @@ -0,0 +1,49 @@ +package ru.tinkoff.edu.java.bot.commands; + +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; +import ru.tinkoff.edu.java.bot.client.ScrapperClientException; +import ru.tinkoff.edu.java.bot.dto.AddLinkRequest; +import ru.tinkoff.edu.java.bot.dto.RemoveLinkRequest; + +@Component +public class UntrackCommand implements Command{ + + private final ScrapperClient scrapperClient; + + private final Link_Parser parser; + + + public UntrackCommand(ScrapperClient scrapperClient, Link_Parser parser) { + this.scrapperClient = scrapperClient; + this.parser = parser; + } + + @Override + public String command() { + return "/untrack"; + } + + @Override + public String description() { + return "ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ отслСТиваниС ссылки"; + } + + @Override + public String handle(Update update) { + long chatId = update.message().chat().id(); + String msg; + try { + if (parser.parseUrl(update.message().text()) != null){ + scrapperClient.deleteLink(chatId, new RemoveLinkRequest(update.message().text())); + msg = "Бсылка ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΡƒΠ΄Π°Π»Π΅Π½Π°"; + } else msg = "НСкоррСктная ссылка"; + return msg; + } catch (ScrapperClientException e) { + return e.getMessage(); + } + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java new file mode 100644 index 0000000..02ab1d4 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import jakarta.validation.constraints.NotNull; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +@Validated +@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) +public record ApplicationConfig(@NotNull String test, + String queueName, + String exchangeName, + String routingKey) {} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java new file mode 100644 index 0000000..31177f6 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java @@ -0,0 +1,78 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import ru.tinkoff.edu.java.bot.commands.Command; +import ru.tinkoff.edu.java.bot.commands.CommandsEnum; +import ru.tinkoff.edu.java.bot.commands.HelpCommand; +import ru.tinkoff.edu.java.bot.commands.ListCommand; +import ru.tinkoff.edu.java.bot.commands.StartCommand; +import ru.tinkoff.edu.java.bot.commands.TrackCommand; +import ru.tinkoff.edu.java.bot.commands.UntrackCommand; +import ru.tinkoff.edu.java.bot.dto.BotCommand; +import ru.tinkoff.edu.java.bot.dto.SetCommandRequest; +import ru.tinkoff.edu.java.bot.telegram.Bot; + +@Configuration +@Slf4j +public class BotConfiguration { + + @Value("${tg.bot.token}") + private String token; + + @Value("${tg.api.baseUrl}") + private String tgApiBaseUrl; + + private final HelpCommand helpCommand; + private final StartCommand startCommand; + private final ListCommand listCommand; + private final TrackCommand trackCommand; + private final UntrackCommand untrackCommand; + + public BotConfiguration( + HelpCommand helpCommand, + StartCommand startCommand, + ListCommand listCommand, + TrackCommand trackCommand, + UntrackCommand untrackCommand + ) { + this.helpCommand = helpCommand; + this.startCommand = startCommand; + this.listCommand = listCommand; + this.trackCommand = trackCommand; + this.untrackCommand = untrackCommand; + } + + @Bean + public Bot bot() { + EnumMap commands = new EnumMap<>(CommandsEnum.class); + + commands.put(CommandsEnum.HELP, helpCommand); + commands.put(CommandsEnum.LIST, listCommand); + commands.put(CommandsEnum.START, startCommand); + commands.put(CommandsEnum.TRACK, trackCommand); + commands.put(CommandsEnum.UNTRACK, untrackCommand); + + //Π”Π΅Π»Π°Π΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ "МСню" рядом с ΠΈΠΊΠΎΠ½ΠΊΠΎΠΉ скрСпки + //Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ запрос Π½Π° API Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌΠΌΠ° (ΠΌΠ΅Ρ‚ΠΎΠ΄ setMyCommands) со списком ΠΊΠΎΠΌΠ°Π½Π΄ Π² Π²ΠΈΠ΄Π΅ List + List apiCommands = new ArrayList<>(commands.values().stream().map(Command::toApiCommand).toList()); + WebClient botConfClient = WebClient.create(tgApiBaseUrl + token); + botConfClient.post().uri("/setMyCommands").bodyValue(new SetCommandRequest(apiCommands)).exchangeToMono(r -> { + if (!r.statusCode().equals(HttpStatus.OK)) { + log.warn("ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ API Telegram нСдоступСн("); + } + return Mono.empty(); + }).block(); + + return new Bot(token, commands); + } + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java new file mode 100644 index 0000000..f5d3a09 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java @@ -0,0 +1,27 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.client.WebClient; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; + + +@Configuration +public class ClientConfiguration { + + @Value("${scrapper.baseurl}") + private String scrapperBaseUrl; + + + @Bean + public WebClient webClient(){ + return WebClient.create(scrapperBaseUrl); + } + + //РСгистрируСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠ°ΠΊ Π±ΠΈΠ½Ρ‹ + @Bean + public ScrapperClient scrapperClient() { + return new ScrapperClient(scrapperBaseUrl); + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java new file mode 100644 index 0000000..eea3511 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java @@ -0,0 +1,15 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; + + +@Configuration +public class LinkParserConfiguration { + + @Bean + public Link_Parser linkParser(){ + return new Link_Parser(); + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java new file mode 100644 index 0000000..fb0772c --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java @@ -0,0 +1,77 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.support.converter.ClassMapper; +import org.springframework.amqp.support.converter.DefaultClassMapper; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.bot.dto.LinkUpdate; +import ru.tinkoff.edu.java.bot.service.ScrapperQueueListener; +import ru.tinkoff.edu.java.bot.service.UpdateService; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class RabbitMQConfiguration { + + private final ApplicationConfig config; + + public RabbitMQConfiguration(ApplicationConfig config) { + this.config = config; + } + + @Bean + Queue queue() { + return QueueBuilder.durable(config.queueName()) + .withArgument("x-dead-letter-exchange", config.exchangeName()) + .withArgument("x-dead-letter-routing-key", config.routingKey() + ".dlq") + .build(); + } + + @Bean + Queue deadLetterQueue() { + return new Queue(config.queueName() + ".dlq", true); + } + + @Bean + DirectExchange exchange() { + return new DirectExchange(config.exchangeName()); + } + + @Bean + Binding binding(Queue queue, DirectExchange exchange) { + return BindingBuilder.bind(queue).to(exchange).with(config.routingKey()); + } + + @Bean + Binding dlqBinding(Queue deadLetterQueue, DirectExchange exchange) { + return BindingBuilder.bind(deadLetterQueue).to(exchange).with(config.routingKey() + ".dlq"); + } + + @Bean + public ClassMapper classMapper() { + Map> mappings = new HashMap<>(); + mappings.put("ru.tinkoff.edu.java.scrapper.dto.LinkUpdate", LinkUpdate.class); + + DefaultClassMapper classMapper = new DefaultClassMapper(); + classMapper.setTrustedPackages("ru.tinkoff.edu.java.scrapper.dto.*"); + classMapper.setIdClassMapping(mappings); + return classMapper; + } + + @Bean + public MessageConverter jsonMessageConverter(ClassMapper classMapper) { + Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter(); + jsonConverter.setClassMapper(classMapper); + return jsonConverter; + } + + @Bean + public ScrapperQueueListener scrapperQueueListener(AmqpTemplate rabbitTemplate, UpdateService updateService) { + return new ScrapperQueueListener(rabbitTemplate, updateService); + } + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java new file mode 100644 index 0000000..1ff0bee --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.bot.dto; + + +public record AddLinkRequest(String link) { + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java new file mode 100644 index 0000000..d8d6113 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java @@ -0,0 +1,7 @@ +package ru.tinkoff.edu.java.bot.dto; + +public record ApiErrorResponse(String description, String code, String exceptionName, + String exceptionMessage, String[] stacktrace) { + + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java new file mode 100644 index 0000000..201c5c6 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.bot.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + +public record BotCommand(@JsonProperty("command") String command, @JsonProperty("description") String description) implements Serializable { + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java new file mode 100644 index 0000000..2ab0a84 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java @@ -0,0 +1,10 @@ +package ru.tinkoff.edu.java.bot.dto; + +import java.net.URI; + +public record Link (Long id, URI url){ + @Override + public String toString() { + return "Link{" + "id=" + id + ", url='" + url + '\'' +'}'; + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java new file mode 100644 index 0000000..396f750 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.bot.dto; + +import java.net.URI; + +public record LinkResponse(long id, URI url) { + + @Override + public String toString() { + return "LinkResponse{" + "id=" + id + ", url=" + url +'}'; + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java new file mode 100644 index 0000000..8a92e00 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.bot.dto; + +public record LinkUpdate(Long id, String url, String description, Long[] tgChatIds) { + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java new file mode 100644 index 0000000..5d23d7b --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.bot.dto; + +import java.util.List; + +public record ListLinkResponse(List links, int size) { +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java new file mode 100644 index 0000000..7e58ba4 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.bot.dto; + +public record RemoveLinkRequest(String link) { + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java new file mode 100644 index 0000000..799cdc3 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java @@ -0,0 +1,7 @@ +package ru.tinkoff.edu.java.bot.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +public record SetCommandRequest(@JsonProperty("commands") List commands) { +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java new file mode 100644 index 0000000..d21ec6a --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.bot.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record UserAddDto(@JsonProperty("username") String username, + @JsonProperty("first_name") String firstName, + @JsonProperty("last_name") String lastName) { +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java new file mode 100644 index 0000000..524f6f3 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java @@ -0,0 +1,10 @@ +package ru.tinkoff.edu.java.bot.exceptions; + +public class ChatNotFoundException extends RuntimeException { + public ChatNotFoundException() { + } + + public ChatNotFoundException(String message) { + super(message); + } +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java new file mode 100644 index 0000000..98c36ae --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java @@ -0,0 +1,10 @@ +package ru.tinkoff.edu.java.bot.exceptions; + +public class LinkIsNotRegisteredToChatException extends RuntimeException { + public LinkIsNotRegisteredToChatException() { + } + + public LinkIsNotRegisteredToChatException(String message) { + super(message); + } +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java new file mode 100644 index 0000000..2120e54 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java @@ -0,0 +1,29 @@ +package ru.tinkoff.edu.java.bot.rest; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import ru.tinkoff.edu.java.bot.dto.LinkUpdate; +import ru.tinkoff.edu.java.bot.service.UpdateService; +import ru.tinkoff.edu.java.bot.service.UpdateServiceImpl; + +@RestController +@Slf4j +public class BotRestController { + + private final UpdateService updateService; + + + public BotRestController(UpdateService updateService) { + this.updateService = updateService; + } + + @PostMapping("updates") + public void sendUpdate(@RequestBody LinkUpdate request) { + log.info("ΠŸΡ€ΠΈΡˆΡ‘Π» запрос Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅: "+request); + updateService.updateLink(request); + } + + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java new file mode 100644 index 0000000..3cdef00 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java @@ -0,0 +1,29 @@ +package ru.tinkoff.edu.java.bot.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.core.AmqpTemplate; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import ru.tinkoff.edu.java.bot.dto.LinkUpdate; + +@RabbitListener(queues = "${app.queue-name}") +@Slf4j +public class ScrapperQueueListener { + + private final AmqpTemplate rabbitTemplate; + + private final UpdateService updateService; + + public ScrapperQueueListener(AmqpTemplate rabbitTemplate, UpdateService updateService) { + this.rabbitTemplate = rabbitTemplate; + this.updateService = updateService; + } + + @RabbitHandler + public void receiver(LinkUpdate update) { + log.info("Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ: " + update); +// throw new RuntimeException("test exception"); + updateService.updateLink(update); + } + +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java new file mode 100644 index 0000000..ed22af0 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.bot.service; + +import ru.tinkoff.edu.java.bot.dto.LinkUpdate; + +public interface UpdateService { + +void updateLink(LinkUpdate linkUpdate); +} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java new file mode 100644 index 0000000..0e0531d --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.bot.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.tinkoff.edu.java.bot.dto.LinkUpdate; +import ru.tinkoff.edu.java.bot.telegram.Bot; + +@Service +@Slf4j +public class UpdateServiceImpl implements UpdateService { + + private final Bot bot; + + public UpdateServiceImpl(Bot bot) { + this.bot = bot; + } + + public void updateLink(LinkUpdate linkUpdate) { + log.info("updateLink() method invocation in UpdateServiceImpl"); + String message = "Π’Ρ‹ΡˆΠ»ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎ ссылкС " + linkUpdate.url() + " \n" + linkUpdate.description(); + for (Long chatId : linkUpdate.tgChatIds()) { + bot.sendMessage(chatId, message); + } + } + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java new file mode 100644 index 0000000..050e804 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java @@ -0,0 +1,52 @@ +package ru.tinkoff.edu.java.bot.telegram; + +import com.pengrad.telegrambot.TelegramBot; +import com.pengrad.telegrambot.UpdatesListener; +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.request.SendMessage; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import ru.tinkoff.edu.java.bot.commands.Command; +import ru.tinkoff.edu.java.bot.commands.CommandsEnum; + +import java.util.EnumMap; + +@Slf4j +public class Bot implements AutoCloseable { + + private final TelegramBot bot; + private final UserMessageProcessor userMessageProcessor; + + @PostConstruct + public void init() { + start(); + } + + public Bot(String token, EnumMap commands) { + log.info("Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±ΠΎΡ‚Π°... Π’ΠΎΠΊΠ΅Π½: " + token); + userMessageProcessor = new UserMessageProcessor(commands); + bot = new TelegramBot(token); + } + + public void start() { + log.info("Π‘ΠΎΡ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½..."); + bot.setUpdatesListener(updates -> { + for (Update update : updates) { + if (update.message() != null) { + bot.execute(new SendMessage(update.message().chat().id(), userMessageProcessor.process(update))); + } + + } + return UpdatesListener.CONFIRMED_UPDATES_ALL; + }); + } + + public void sendMessage(Long chatId, String msg) { + bot.execute(new SendMessage(chatId, msg)); + } + + @Override + public void close() throws Exception { + bot.removeGetUpdatesListener(); + } +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java new file mode 100644 index 0000000..ac7b8ac --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java @@ -0,0 +1,126 @@ +package ru.tinkoff.edu.java.bot.telegram; + +import com.pengrad.telegrambot.model.Update; +import ru.tinkoff.edu.java.bot.commands.*; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +public class UserMessageProcessor { + +// private final List commands; + + // БостояниС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. НуТно для ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ /track ΠΈ /untrack + // TYPING_COMMAND - состояниС Π²Π²ΠΎΠ΄Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ) + // TYPING_TRACKED - состояниС Π²Π²ΠΎΠ΄Π° ссылки для добавлСния + // TYPING_UNTRACKED - состояниС Π²Π²ΠΎΠ΄Π° ссылки для удалСния + private final Map userStateMap; + + private final EnumMap commands; + + public UserMessageProcessor(EnumMap commands) { + this.commands = commands; + userStateMap = new HashMap<>(); + } + + public String process(Update update) { + Command command; + + userStateMap.putIfAbsent(update.message().chat().id(), UserState.TYPING_COMMAND); + switch (userStateMap.get(update.message().chat().id())) { + case TYPING_TRACKED -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + return commands.get(CommandsEnum.valueOfLabel("/track")).handle(update); + } + case TYPING_UNTRACKED -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + return commands.get(CommandsEnum.valueOfLabel("/untrack")).handle(update); + } + case TYPING_COMMAND -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + command = commands.get(CommandsEnum.valueOfLabel(update.message().text())); + if (command == null) { + return "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; + } + if (command instanceof TrackCommand) { + userStateMap.put(update.message().chat().id(), UserState.TYPING_TRACKED); + return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; + } + if (command instanceof UntrackCommand) { + userStateMap.put(update.message().chat().id(), UserState.TYPING_UNTRACKED); + return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; + } + if (command instanceof HelpCommand) { + StringBuilder text = new StringBuilder(); + for (Command c : commands.values()) { + text.append(c.command()).append(" - ").append(c.description()).append("\n"); + } + return text.toString(); + } + return command.handle(update); + } + default -> { + //По Π»ΠΎΠ³ΠΈΠΊΠ΅ этот return Π½ΠΈΠΊΠ°ΠΊ нСдостиТим + return "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° нашСй сторонС"; + + } + } + + } + + }vate final Map userStateMap; + + private final EnumMap commands; + + + public UserMessageProcessor(EnumMap commands) { + this.commands = commands; + userStateMap = new HashMap<>(); + } + + public String process(Update update) { + Command command; + + + userStateMap.putIfAbsent(update.message().chat().id(), UserState.TYPING_COMMAND); + switch (userStateMap.get(update.message().chat().id())) { + case TYPING_TRACKED -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + return commands.get(CommandsEnum.valueOfLabel("/track")).handle(update); + } + case TYPING_UNTRACKED -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + return commands.get(CommandsEnum.valueOfLabel("/untrack")).handle(update); + } + case TYPING_COMMAND -> { + userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); + command = commands.get(CommandsEnum.valueOfLabel(update.message().text())); + if (command == null) + return "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; + if (command instanceof TrackCommand) { + userStateMap.put(update.message().chat().id(), UserState.TYPING_TRACKED); + return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; + } + if (command instanceof UntrackCommand) { + userStateMap.put(update.message().chat().id(), UserState.TYPING_UNTRACKED); + return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; + } + if (command instanceof HelpCommand){ + StringBuilder text = new StringBuilder(); + for (Command c : commands.values()) { + text.append(c.command()).append(" - ").append(c.description()).append("\n"); + } + return text.toString(); + } + return command.handle(update); + } + default -> { + + return "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° Π½Π°ΡˆΠ΅Ρ‘ сторонС"; + } + } + + } + + +} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java new file mode 100644 index 0000000..70bc584 --- /dev/null +++ b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.bot.telegram; + +public enum UserState { + TYPING_COMMAND, TYPING_TRACKED, TYPING_UNTRACKED +} diff --git a/FP/FP/bot/src/main/resources/application.properties b/FP/FP/bot/src/main/resources/application.properties new file mode 100644 index 0000000..bf1fbc5 --- /dev/null +++ b/FP/FP/bot/src/main/resources/application.properties @@ -0,0 +1,14 @@ +app.test=beamer-bot +server.port=8080 +springdoc.swagger-ui.path=/swagger-ui +scrapper.baseurl=http://localhost:8080 +tg.bot.token=${TGBOTTOKEN} +tg.api.baseUrl=https://api.telegram.org/bot +spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=romanova +spring.rabbitmq.password=2281337 +spring.rabbitmq.listener.simple.default-requeue-rejected=false +app.queue-name=scrapper-bot-queue +app.exchange-name=scrapper-bot-exchange +app.routing-key=scrapper-bot-key \ No newline at end of file diff --git a/FP/FP/bot/src/test/java/bot/BotTest.java b/FP/FP/bot/src/test/java/bot/BotTest.java new file mode 100644 index 0000000..af954d2 --- /dev/null +++ b/FP/FP/bot/src/test/java/bot/BotTest.java @@ -0,0 +1,123 @@ +package bot; + +import com.pengrad.telegrambot.model.Chat; +import com.pengrad.telegrambot.model.Message; +import com.pengrad.telegrambot.model.Update; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.test.util.ReflectionTestUtils; +import ru.tinkoff.edu.java.bot.client.ScrapperClient; +import ru.tinkoff.edu.java.bot.commands.Command; +import ru.tinkoff.edu.java.bot.commands.CommandsEnum; +import ru.tinkoff.edu.java.bot.commands.ListCommand; +import ru.tinkoff.edu.java.bot.dto.Link; +import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; +import ru.tinkoff.edu.java.bot.telegram.UserMessageProcessor; +import ru.tinkoff.edu.java.bot.telegram.UserState; + +import java.net.URI; +import java.util.*; + +public class BotTest { + + static UserMessageProcessor userMessageProcessor; + + static ScrapperClient scrapperClient; + + static Update updateForListCommand; + static Update updateForInvalidCommand; + static Message messageForListCommand; + static Message messageForInvalidCommand; + + static Chat chat; + + @BeforeAll + static void init() { + //ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π°Π³Π»ΡƒΡˆΠΊΠΈ ΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Ρ‹Π½Π½Ρ‹Π΅, Ρ‚.ΠΊ. Ρƒ Update Π² Π½Π΅Ρ‚ сСттСров, Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ€Π΅Ρ„Π»Π΅ΠΊΡΠΈΡŽ, + //Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ‚ΡƒΠ΄Π° Π½ΡƒΠΆΠ½Ρ‹ΠΉ Message + scrapperClient = Mockito.mock(ScrapperClient.class); + updateForListCommand = new Update(); + messageForListCommand = new Message(); + chat = new Chat(); + ReflectionTestUtils.setField(chat, "id", 42L); + ReflectionTestUtils.setField(messageForListCommand, "chat", chat); + ReflectionTestUtils.setField(messageForListCommand, "text", "/list"); + ReflectionTestUtils.setField(updateForListCommand, "message", messageForListCommand); + + updateForInvalidCommand = new Update(); + messageForInvalidCommand = new Message(); + + ReflectionTestUtils.setField(messageForInvalidCommand, "chat", chat); + ReflectionTestUtils.setField(messageForInvalidCommand, "text", "Azazelo"); + ReflectionTestUtils.setField(updateForInvalidCommand, "message", messageForInvalidCommand); + } + + @Test + @DisplayName("ВСст ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /list, ΠΊΠΎΠ³Π΄Π° список ссылок нСпустой") + public void listCommandTestNotEmpty() { + + //ΠΈΠΌΠΈΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½ΡƒΠΆΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° для Scrapper, Ρ‚.ΠΊ. Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ запроса Π½Π° Scrapper Π²ΠΎ врСмя Π½Π΅ происходит + List listLink = new ArrayList<>(); + listLink.add(new Link(1L, URI.create("https://github.com/lwbeamer/asm-like-language"))); + listLink.add(new Link(2L, URI.create("https://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface"))); + Mockito.when(scrapperClient.getLinks(42L)).thenReturn( + new ListLinkResponse(listLink, listLink.size()) + ); + + EnumMap map = new EnumMap<>(CommandsEnum.class); + map.put(CommandsEnum.LIST, new ListCommand(scrapperClient)); + + userMessageProcessor = new UserMessageProcessor(map); + + String expectedMessage = """ + Бсылок отслСТиваСтся - 2 + + https://github.com/lwbeamer/asm-like-language + + https://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface + + """; + + Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForListCommand)); + } + + + @Test + @DisplayName("ВСст ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /list, ΠΊΠΎΠ³Π΄Π° список ссылок пустой") + public void listCommandTestEmpty() { + Mockito.when(scrapperClient.getLinks(42L)).thenReturn( + new ListLinkResponse(new ArrayList<>(), 0) + ); + + + EnumMap map = new EnumMap<>(CommandsEnum.class); + map.put(CommandsEnum.LIST, new ListCommand(scrapperClient)); + + userMessageProcessor = new UserMessageProcessor(map); + + + String expectedMessage = "Бписок отслСТиваСмых ссылок пуст!"; + + Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForListCommand)); + } + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π²ΠΎΠ΄Π° нСизвСстной ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹") + public void invalidCommandCheck() { + userMessageProcessor = new UserMessageProcessor(new EnumMap<>(CommandsEnum.class)); + + //УстанавливаСм состояниС ΠΏΠ΅Ρ€Π΅Π΄ тСстом - ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π² сосвтоянии "ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ" + Map userStateMap = new HashMap<>(); + userStateMap.put(chat.id(), UserState.TYPING_COMMAND); + ReflectionTestUtils.setField(userMessageProcessor, "userStateMap", userStateMap); + + String expectedMessage = "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; + + Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForInvalidCommand)); + + } + +} \ No newline at end of file diff --git a/FP/FP/docker-compose.yml b/FP/FP/docker-compose.yml new file mode 100644 index 0000000..c472659 --- /dev/null +++ b/FP/FP/docker-compose.yml @@ -0,0 +1,60 @@ +services: + postgresql: + image: postgres:15 + container_name: postgresql + ports: + - 5432:5432 + environment: + - POSTGRES_USER=lwbeamer + - POSTGRES_PASSWORD=2281337 + - POSTGRES_DB=scrapper + volumes: + - link-service-data:/var/lib/postgresql/data + networks: + - backend + + liquibase-migrations: + image: liquibase/liquibase:4.18 + depends_on: + - postgresql + command: + - --hub-mode=off + - --changelog-file=master.xml + - --driver=org.postgresql.Driver + - --url=jdbc:postgresql://postgresql:5432/scrapper + - --username=romanova + - --password=12345654321 + - update + volumes: + - ./migrations:/liquibase/changelog + networks: + - backend + +volumes: + link-service-data: + +networks: + backend: + name: backend + rabbit: + image: rabbitmq:3-management + hostname: rabbitmq + container_name: rabbit + ports: + - 15672:15672 + - 5672:5672 + environment: + - RABBITMQ_DEFAULT_USER=romanova + - RABBITMQ_DEFAULT_PASS=12345654321 + volumes: + - rabbitmq-state:/var/lib/rabbitmq + networks: + - backend + +volumes: + link-service-data: + rabbitmq-state: + +networks: + backend: + name: backend \ No newline at end of file diff --git a/FP/FP/link-parser/.classpath b/FP/FP/link-parser/.classpath new file mode 100644 index 0000000..a08fc4f --- /dev/null +++ b/FP/FP/link-parser/.classpath @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FP/FP/link-parser/.gitignore b/FP/FP/link-parser/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/FP/FP/link-parser/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/FP/FP/link-parser/.project b/FP/FP/link-parser/.project new file mode 100644 index 0000000..dec0f32 --- /dev/null +++ b/FP/FP/link-parser/.project @@ -0,0 +1,23 @@ + + + link-parser + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs b/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs b/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..5e4ec05 --- /dev/null +++ b/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs b/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/FP/FP/link-parser/pom.xml b/FP/FP/link-parser/pom.xml new file mode 100644 index 0000000..3cfd292 --- /dev/null +++ b/FP/FP/link-parser/pom.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + project + project + 0.0.1-SNAPSHOT + + link-parser + + + org.junit.jupiter + junit-jupiter-params + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java new file mode 100644 index 0000000..e244c93 --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.link_parser.link; + +public record GitHub_Link(String username, String repository) implements Parser_Link { + +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java new file mode 100644 index 0000000..75db93c --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.link_parser.link; + +public sealed interface Parser_Link permits GitHub_Link, StackOverflow_Link { + +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java new file mode 100644 index 0000000..1dad8ad --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.link_parser.link; + +public record StackOverflow_Link(long id) implements Parser_Link { + +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java new file mode 100644 index 0000000..f3641fc --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java @@ -0,0 +1,27 @@ +package ru.tinkoff.edu.java.link_parser.parser; + +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; +import java.net.MalformedURLException; +import java.net.URL; + +public abstract class Abstract { + + Abstract nextParser; + + public Abstract(Abstract nextParser) { + this.nextParser = nextParser; + } + + public abstract Parser_Link parser_Link(String url); + + public final URL tweakUrl(String urlString) { + URL url; + try{ + url = new URL(urlString); + } catch (MalformedURLException e){ + System.out.println("Incorrect URL"); + return null; + } + return url; + } +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java new file mode 100644 index 0000000..13ae325 --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java @@ -0,0 +1,31 @@ +package ru.tinkoff.edu.java.link_parser.parser; + +import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; + +import java.net.URL; + + +public class Github extends Abstract { + public Github(Abstract nextParser) { + super(nextParser); + } + + @Override + public Parser_Link parser_Link(String url) { + URL toParse = tweakUrl(url); + if (toParse == null) return null; + + if (toParse.getHost().equals("github.com")) { + String[] tokens = toParse.getFile().substring(1).split("/"); + if (tokens.length >= 2) { + return new GitHub_Link(tokens[0], tokens[1]); + } else return null; + } + + + if (nextParser != null) return nextParser.parser_Link(url); + + return null; + } +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java new file mode 100644 index 0000000..fac1e3f --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java @@ -0,0 +1,16 @@ +package ru.tinkoff.edu.java.link_parser.parser; + +import ru.tinkoff.edu.java.link_parser.parser.Abstract; +import ru.tinkoff.edu.java.link_parser.parser.Github; +import ru.tinkoff.edu.java.link_parser.parser.StackOverflow; +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; + +public class Link_Parser { + public Parser_Link parseUrl(String url) { + Abstract parser1 = new Github(null); + Abstract parser2 = new StackOverflow(parser1); + + return parser2.parser_Link(url); + } + +} diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java new file mode 100644 index 0000000..e224578 --- /dev/null +++ b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java @@ -0,0 +1,34 @@ +package ru.tinkoff.edu.java.link_parser.parser; + +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; +import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; +import java.net.URL; +public class StackOverflow extends Abstract { + public StackOverflow(Abstract nextParser) { + super(nextParser); + } + + @Override + public Parser_Link parser_Link(String url) { + + URL toParse = tweakUrl(url); + if (toParse == null) return null; + + + if (toParse.getHost().equals("stackoverflow.com")) { + String[] tokens = toParse.getFile().substring(1).split("/"); + if (tokens.length >= 2 && tokens[0].equals("questions")) { + try { + return new StackOverflow_Link(Long.parseLong(tokens[1])); + } catch (NumberFormatException e) { + System.out.println("Incorrect question ID"); + return null; + } + } else return null; + } + + if (nextParser != null) return nextParser.parser_Link(url); + + return null; + } +} \ No newline at end of file diff --git a/FP/FP/link-parser/src/test/java/LinkParserTest.java b/FP/FP/link-parser/src/test/java/LinkParserTest.java new file mode 100644 index 0000000..bef7512 --- /dev/null +++ b/FP/FP/link-parser/src/test/java/LinkParserTest.java @@ -0,0 +1,99 @@ +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import ru.tinkoff.edu.java.link_parser.parser.*; +import ru.tinkoff.edu.java.link_parser.link.*; + +public class LinkParserTest { + + static String validGitHubLink; + static String validStackOverflowLink; + static String gitHubNotRepoLink; + static String stackOverflowNotQuestionLink; + static String emptyLink; + static String withoutProtocolLink; + static String unknownHostLink; + static String invalidLink; + + + @BeforeAll + static void init() { + validGitHubLink = "https://github.com/lwbeamer/asm-like-language"; + validStackOverflowLink = "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"; + gitHubNotRepoLink = "https://github.com/issues"; + stackOverflowNotQuestionLink = "https://stackoverflow.co/talent"; + emptyLink = ""; + withoutProtocolLink = "github.com/lwbeamer/asm-like-language"; + unknownHostLink = "https://vk.com/feed"; + invalidLink = "somethingNotValid"; + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки с GitHub") + void checkValidGitHubLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertEquals(new GitHub_Link("lwbeamer", "asm-like-language"), parser.parseUrl(validGitHubLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки со StackOverflow") + void validStackOverflowLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertEquals(new StackOverflow_Link(2336692), parser.parseUrl(validStackOverflowLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки с GitHub, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅ΠΉΡΡ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠ΅ΠΌ") + void gitHubNotRepoLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(gitHubNotRepoLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки со StackOverflow, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅ΠΉΡΡ вопросом") + void stackOverflowNotQuestionLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(stackOverflowNotQuestionLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ пустой ссылки") + void emptyLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(emptyLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки Π±Π΅Π· указания ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°") + void withoutProtocolLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(withoutProtocolLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки, Π½Π΅ относящСйся ΠΊ отслСТиваСмым рСсурсам") + void unknownHostLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(unknownHostLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ нСпустой Π½Π΅Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки") + void invalidLink() { + Link_Parser parser = new Link_Parser(); + Assertions.assertNull(parser.parseUrl(invalidLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); + } + + +} diff --git a/FP/FP/migrations/01-schema-1.sql b/FP/FP/migrations/01-schema-1.sql new file mode 100644 index 0000000..838947b --- /dev/null +++ b/FP/FP/migrations/01-schema-1.sql @@ -0,0 +1,11 @@ +--liquibase formatted sql + +--changeset romanova:create-user-table-1 +CREATE TABLE "user" ( + chat_id bigint PRIMARY KEY, + username text UNIQUE NOT NULL, + first_name text, + last_name text +); + +--rollback DROP TABLE "user"; \ No newline at end of file diff --git a/FP/FP/migrations/02-schema-2.sql b/FP/FP/migrations/02-schema-2.sql new file mode 100644 index 0000000..0e40afb --- /dev/null +++ b/FP/FP/migrations/02-schema-2.sql @@ -0,0 +1,15 @@ +--liquibase formatted sql + +--changeset romanova:create-link-table-1 +CREATE TABLE "link" ( + id bigserial PRIMARY KEY, + url text UNIQUE NOT NULL, + checked_at timestamp NOT NULL, + gh_pushed_at timestamp, + gh_description text, + gh_forks_count int, + so_answer_count int, + so_last_edit_date timestamp +); + +--rollback DROP TABLE "link"; \ No newline at end of file diff --git a/FP/FP/migrations/03-schema-3.sql b/FP/FP/migrations/03-schema-3.sql new file mode 100644 index 0000000..c407b73 --- /dev/null +++ b/FP/FP/migrations/03-schema-3.sql @@ -0,0 +1,10 @@ +--liquibase formatted sql + +--changeset romanova:create-user-link-table-1 +CREATE TABLE "user_link" ( + link_id bigint REFERENCES "link" (id), + chat_id bigint REFERENCES "user" (chat_id), + PRIMARY KEY (link_id,chat_id) +); + +--rollback DROP TABLE "user_link"; \ No newline at end of file diff --git a/FP/FP/migrations/create.sql b/FP/FP/migrations/create.sql new file mode 100644 index 0000000..a4e2a68 --- /dev/null +++ b/FP/FP/migrations/create.sql @@ -0,0 +1,18 @@ +create table "user" ( + chat_id bigint primary key, + username text unique not null, + first_name text, + last_name text +); + +create table "link" ( + id bigserial primary key, + url text unique not null, + updated_at timestamp not null +); + +create table "user_link" ( + link_id bigint references "link" (id), + chat_id bigint references "user" (chat_id), + primary key (link_id,chat_id) +) \ No newline at end of file diff --git a/FP/FP/migrations/delete.sql b/FP/FP/migrations/delete.sql new file mode 100644 index 0000000..1fb56bd --- /dev/null +++ b/FP/FP/migrations/delete.sql @@ -0,0 +1,3 @@ +drop table "user_link"; +drop table "user"; +drop table "link"; \ No newline at end of file diff --git a/FP/FP/migrations/insert.sql b/FP/FP/migrations/insert.sql new file mode 100644 index 0000000..30b59be --- /dev/null +++ b/FP/FP/migrations/insert.sql @@ -0,0 +1,37 @@ +insert into "user" (chat_id, username, first_name, last_name) +values (42, 'testUser42', 'test', 'testov'), + (34, 'testUser34', 'test', 'testov'), + (65, 'testUser65', 'test', 'testov'), + (45, 'testUser45', 'test', 'testov'), + (523, 'testUser523', 'test', 'testov'), + (645, 'testUser645', 'test', 'testov'), + (7452, 'testUser7452', 'test', 'testov'), + (44562, 'testUser44562', 'test', 'testov'), + (423452, 'testUser423452', 'test', 'testov'), + (2, 'testUser2', 'test', 'testov'); + +insert into "link" (url, updated_at) +values ('https://stackoverflow.com/questions/14141266/postgresql-foreign-key-on-delete-cascade', '2022-05-19 15:13:27'), + ('https://github.com/linus/doctest','2022-01-31 13:13:50'), + ('https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file','2023-03-27 09:58:45'); + +insert into "user_link" (link_id, chat_id) +values (1,42), + (1,45), + (1,2), + (1,7452), + (2,44562), + (2,423452), + (2,645), + (2,523), + (3,34), + (3,65), + (3,7452), + (3,45), + (4,42), + (4,45), + (4,2), + (4,7452); + + + diff --git a/FP/FP/migrations/master.xml b/FP/FP/migrations/master.xml new file mode 100644 index 0000000..c566afc --- /dev/null +++ b/FP/FP/migrations/master.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/FP/FP/pom.xml b/FP/FP/pom.xml new file mode 100644 index 0000000..a1baa3d --- /dev/null +++ b/FP/FP/pom.xml @@ -0,0 +1,123 @@ + + 4.0.0 + project + project + 0.0.1-SNAPSHOT + pom + + bot + link-parser + scrapper + scrapper-jooq + + + 3.0.1 + 2022.0.0 + 3.10.1 + 23.1.0 + UTF-8 + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + org.springframework.boot + spring-boot-starter-test + ${spring.test.version} + test + + + + + + + + org.jetbrains + annotations + ${annotations.version} + provided + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + true + + + + org.projectlombok + lombok + + + + + + + repackage + build-info + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 17 + true + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + \ No newline at end of file diff --git a/FP/FP/scrapper-jooq/.classpath b/FP/FP/scrapper-jooq/.classpath new file mode 100644 index 0000000..ead1d0f --- /dev/null +++ b/FP/FP/scrapper-jooq/.classpath @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FP/FP/scrapper-jooq/.gitignore b/FP/FP/scrapper-jooq/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/FP/FP/scrapper-jooq/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/FP/FP/scrapper-jooq/.project b/FP/FP/scrapper-jooq/.project new file mode 100644 index 0000000..f320f87 --- /dev/null +++ b/FP/FP/scrapper-jooq/.project @@ -0,0 +1,23 @@ + + + scrapper-jooq + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..609d3ca --- /dev/null +++ b/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/resources=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..5e4ec05 --- /dev/null +++ b/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/FP/FP/scrapper-jooq/pom.xml b/FP/FP/scrapper-jooq/pom.xml new file mode 100644 index 0000000..b6f0785 --- /dev/null +++ b/FP/FP/scrapper-jooq/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + project + project + 0.0.1-SNAPSHOT + + scrapper-jooq + + 17 + 17 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-jooq + + + org.jooq + jooq-codegen + + + org.jooq + jooq-meta-extensions-liquibase + 3.18.3 + + + org.jooq + jooq-postgres-extensions + 3.18.3 + + + org.liquibase + liquibase-core + + + + \ No newline at end of file diff --git a/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java b/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java new file mode 100644 index 0000000..f8a5bc7 --- /dev/null +++ b/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java @@ -0,0 +1,54 @@ +import org.jooq.codegen.GenerationTool; +import org.jooq.meta.jaxb.Configuration; +import org.jooq.meta.jaxb.Database; +import org.jooq.meta.jaxb.Generate; +import org.jooq.meta.jaxb.Generator; +import org.jooq.meta.jaxb.Property; +import org.jooq.meta.jaxb.Target; + +public final class JooqCodegen { + + private JooqCodegen() { + + } + + public static void main(String[] args) throws Exception { + Database database = new Database() + .withName("org.jooq.meta.extensions.liquibase.LiquibaseDatabase") + .withProperties( + new Property().withKey("rootPath").withValue("migrations"), + new Property().withKey("scripts").withValue("master.xml") + ); + + Generate options = new Generate() + .withGeneratedAnnotation(true) + .withGeneratedAnnotationDate(false) + .withNullableAnnotation(true) + .withNullableAnnotationType("org.jetbrains.annotations.Nullable") + .withNonnullAnnotation(true) + .withNonnullAnnotationType("org.jetbrains.annotations.NotNull") + .withJpaAnnotations(false) + .withValidationAnnotations(true) + .withSpringAnnotations(true) + .withConstructorPropertiesAnnotation(true) + .withConstructorPropertiesAnnotationOnPojos(true) + .withConstructorPropertiesAnnotationOnRecords(true) + .withFluentSetters(false) + .withDaos(false) + .withPojos(true); + + Target target = new Target() + .withPackageName("ru.tinkoff.edu.java.scrapper.domain.jooq") + .withDirectory("scrapper/src/main/java"); + + Configuration configuration = new Configuration() + .withGenerator( + new Generator() + .withDatabase(database) + .withGenerate(options) + .withTarget(target) + ); + + GenerationTool.generate(configuration); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/.classpath b/FP/FP/scrapper/.classpath new file mode 100644 index 0000000..a08fc4f --- /dev/null +++ b/FP/FP/scrapper/.classpath @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FP/FP/scrapper/.gitignore b/FP/FP/scrapper/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/FP/FP/scrapper/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/FP/FP/scrapper/.project b/FP/FP/scrapper/.project new file mode 100644 index 0000000..d56fd66 --- /dev/null +++ b/FP/FP/scrapper/.project @@ -0,0 +1,23 @@ + + + scrapper + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs b/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs b/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..5e4ec05 --- /dev/null +++ b/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs b/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/FP/FP/scrapper/pom.xml b/FP/FP/scrapper/pom.xml new file mode 100644 index 0000000..1b0c4fa --- /dev/null +++ b/FP/FP/scrapper/pom.xml @@ -0,0 +1,120 @@ + + + 4.0.0 + + project + project + 0.0.1-SNAPSHOT + + + scrapper + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework + spring-context-indexer + true + + + org.projectlombok + lombok + true + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.0.2 + + + ru.tinkoff.edu + link-parser + 1.0-SNAPSHOT + + + org.testcontainers + junit-jupiter + test + + + org.springframework.boot + spring-boot-starter-test + + + org.testcontainers + postgresql + test + + + org.liquibase + liquibase-core + test + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.postgresql + postgresql + runtime + + + org.jooq + jooq + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-amqp + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java new file mode 100644 index 0000000..fef7338 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java @@ -0,0 +1,22 @@ +package ru.tinkoff.edu.java.scrapper; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; +import org.springframework.scheduling.annotation.EnableScheduling; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; +import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; +import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaSubscriptionServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaTgChatServiceImpl; + + +@SpringBootApplication +@EnableConfigurationProperties(ApplicationConfig.class) +@EnableScheduling +public class ScrapperApplication { + public static void main(String[] args) { + var ctx = SpringApplication.run(ScrapperApplication.class, args); + ApplicationConfig config = ctx.getBean(ApplicationConfig.class); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java new file mode 100644 index 0000000..2e1aacf --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java @@ -0,0 +1,33 @@ +package ru.tinkoff.edu.java.scrapper.advice; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.client.HttpClientErrorException; +import ru.tinkoff.edu.java.scrapper.dto.ApiErrorResponse; +import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; +import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; +import ru.tinkoff.edu.java.scrapper.exception.LinkIsAlreadyAddedException; +import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; + +import java.util.Arrays; + +@RestControllerAdvice +public class AppExceptionHandler { + + @ExceptionHandler({LinkNotFoundException.class, ChatNotFoundException.class}) + @ResponseStatus(value = HttpStatus.NOT_FOUND) + public ApiErrorResponse handleNotFoundExceptions(RuntimeException exception) { + return new ApiErrorResponse( + "Error", HttpStatus.NOT_FOUND.toString(), exception.getClass().getName(), exception.getMessage(), Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new)); + } + + + @ExceptionHandler({ChatAlreadyExistException.class, LinkIsAlreadyAddedException.class}) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public ApiErrorResponse handleBadRequestExceptions(RuntimeException exception) { + return new ApiErrorResponse( + "Error", HttpStatus.BAD_REQUEST.toString(), exception.getClass().getName(), exception.getMessage(), Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new)); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java new file mode 100644 index 0000000..021e3ec --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java @@ -0,0 +1,38 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; +import ru.tinkoff.edu.java.scrapper.exception.BotClientException; +import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; + +@Slf4j +public class BotClient { + + @Value("${bot.baseurl}") + private String botBaseUrl; + + private final WebClient webClient; + + public BotClient(WebClient webClient) { + this.webClient = webClient; + } + + public BotClient(String botBaseUrl) { + this.webClient = WebClient.create(botBaseUrl); + } + + public void updateLink(LinkUpdate request) { + log.info("Sending update request to Bot"); + webClient.post().uri("/updates").bodyValue(request).exchangeToMono(r -> { + if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { + throw new BotClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); + } + return Mono.empty(); + }).block(); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java new file mode 100644 index 0000000..156cf35 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java @@ -0,0 +1,47 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.reactive.function.client.WebClient; +import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; +import org.springframework.http.HttpStatus; +import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; + +public class GitHubClient { + + + @Value("${gh.baseurl}") + private String gitHubBaseUrl; + + private final WebClient webClient; + + //для использования baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (бСрётся ΠΈΠ· properties) + public GitHubClient() { + this.webClient = WebClient.create(gitHubBaseUrl); + } + + + //ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ URL + public GitHubClient(String baseUrl) { + this.webClient = WebClient.create(baseUrl); + } + + + public GitHubResponse fetchRepo(String owner, String repo) { + GitHubResponse response = webClient.get().uri("/repos/{owner}/{repo}", owner, repo).exchangeToMono(r->{ + if (!r.statusCode().equals(HttpStatus.OK)) throw new GitHubRequestException("Error with request to GH API"); + return r.bodyToMono(GitHubResponse.class); + }).block(); + + return response; + + } + public void strFetchRepo(String owner, String repo){ + String strReponse = webClient.get().uri("/repos/{owner}/{repo}", owner, repo).exchangeToMono(r->{ + if (!r.statusCode().equals(HttpStatus.OK)) throw new GitHubRequestException("Error with request to GH API"); + return r.bodyToMono(String.class); + }).block(); + + System.out.println(strReponse); + + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java new file mode 100644 index 0000000..6651dd9 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java @@ -0,0 +1,44 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.http.HttpStatus; +import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; +import ru.tinkoff.edu.java.scrapper.dto.StackOverflowResponse; +import ru.tinkoff.edu.java.scrapper.exception.BadResponseFromApiException; +import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; +import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; +import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; + +public class StackOverflowClient { + + @Value("${so.baseurl}") + private String stackOverflowBaseUrl; + + private final WebClient webClient; + + + //для использования baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (бСрётся ΠΈΠ· properties) + public StackOverflowClient() { + this.webClient = WebClient.create(stackOverflowBaseUrl); + } + + + //ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ URL + public StackOverflowClient(String baseUrl) { + this.webClient = WebClient.create(baseUrl); + } + + public StackOverflowItem fetchQuestion(long id) { + + StackOverflowResponse response = webClient.get().uri("/questions/{id}?order=desc&sort=activity&site=stackoverflow", id).exchangeToMono(r->{ + if (!r.statusCode().equals(HttpStatus.OK)) throw new StackOverflowRequestException("Error with request to SO API"); + return r.bodyToMono(StackOverflowResponse.class); + }).block(); + + if (response == null || response.items().size() == 0) + throw new BadResponseFromApiException("API StackOverflow returned bad response"); + + return response.items().get(0); + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java new file mode 100644 index 0000000..856e54e --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import jakarta.validation.constraints.NotNull; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.validation.annotation.Validated; +import ru.tinkoff.edu.java.scrapper.schedule.Scheduler; + +@Validated +@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) +public record ApplicationConfig(@NotNull String test, + @NotNull Scheduler scheduler, + @NotNull AccessType dataBaseAccessType, + @NotNull Boolean useQueue, + String queueName, + String exchangeName, + String routingKey){ + + @Bean + public long schedulerIntervalMs(ApplicationConfig config) { + return config.scheduler().interval().toMillis(); + } + public enum AccessType { + JDBC, JPA, JOOQ + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java new file mode 100644 index 0000000..8694acf --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java @@ -0,0 +1,44 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import org.springframework.web.reactive.function.client.WebClient; +import ru.tinkoff.edu.java.scrapper.client.BotClient; + +@Configuration +public class ClientConfiguration { + + @Value("${gh.baseurl}") + private String gitHubBaseUrl; + + @Value("${so.baseurl}") + private String stackOverflowBaseUrl; + + @Value("${bot.baseurl}") + private String botBaseUrl; + + + //РСгистрируСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠ°ΠΊ Π±ΠΈΠ½Ρ‹ + @Bean + public GitHubClient gitHubClientService() { + return new GitHubClient(gitHubBaseUrl); + } + + @Bean + public StackOverflowClient stackOverflowClientService() { + return new StackOverflowClient(stackOverflowBaseUrl); + } + @Bean + public WebClient ghWebClient(){ + return WebClient.create(gitHubBaseUrl); + } + + @Bean + public WebClient soWebClient(){ + return WebClient.create(stackOverflowBaseUrl); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java new file mode 100644 index 0000000..df6780e --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java @@ -0,0 +1,28 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.client.WebClient; +import ru.tinkoff.edu.java.scrapper.client.BotClient; + +@Configuration +@ConditionalOnProperty(prefix = "app", name = "use-queue", havingValue = "false") +public class HTTPConfiguration { + + @Value("${bot.baseurl}") + private String botBaseUrl; + + + @Bean + public BotClient botClient(){return new BotClient(botBaseUrl);} + + @Bean + public WebClient botWebClient(){ + return WebClient.create(botBaseUrl); + } + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java new file mode 100644 index 0000000..e400f15 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java @@ -0,0 +1,14 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; + +@Configuration +public class LinkParserConfiguration { + + @Bean + public Link_Parser linkParser(){ + return new Link_Parser(); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java new file mode 100644 index 0000000..d8b1217 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java @@ -0,0 +1,50 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.scrapper.service.ScrapperQueueProducer; + +@Configuration +@ConditionalOnProperty(prefix = "app", name = "use-queue", havingValue = "true") +public class RabbitMQConfiguration { + + private final ApplicationConfig config; + + public RabbitMQConfiguration(ApplicationConfig config) { + this.config = config; + } + + @Bean + Queue queue() { + return QueueBuilder.durable(config.queueName()) + .withArgument("x-dead-letter-exchange", config.exchangeName()) + .withArgument("x-dead-letter-routing-key", config.routingKey() + ".dlq") + .build(); + } + + @Bean + DirectExchange exchange() { + return new DirectExchange(config.exchangeName()); + } + + @Bean + Binding binding(Queue queue, DirectExchange exchange) { + return BindingBuilder.bind(queue).to(exchange).with(config.routingKey()); + } + + @Bean + public MessageConverter jsonMessageConverter() { + return new Jackson2JsonMessageConverter(); + } + + + @Bean + public ScrapperQueueProducer scrapperQueueProducer(AmqpTemplate rabbitTemplate) { + return new ScrapperQueueProducer(rabbitTemplate, config); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java new file mode 100644 index 0000000..d70f747 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java @@ -0,0 +1,99 @@ +package ru.tinkoff.edu.java.scrapper.configuration.database.acess; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.link_parser.Link_Parser; +import ru.tinkoff.edu.java.scrapper.client.BotClient; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; +import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; +import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.SubscriptionJdbcTemplateRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.UserJdbcTemplateRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; +import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; +import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.LinkUpdateServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.SubscriptionServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; + +@Configuration +@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jdbc") +public class JdbcAccessConfiguration { + + @Bean + public LinkRowMapper linkRowMapper() { + return new LinkRowMapper(); + } + + @Bean + public SubscriptionRowMapper subscriptionRowMapper() { + return new SubscriptionRowMapper(); + } + + @Bean + public UserRowMapper userRowMapper() { + return new UserRowMapper(); + } + + @Bean + public LinkRepository linkRepository(JdbcTemplate jdbcTemplate, LinkRowMapper linkRowMapper) { + return new LinkJdbcTemplateRepository(jdbcTemplate, linkRowMapper); + } + + @Bean + public SubscriptionRepository subscriptionRepository(JdbcTemplate jdbcTemplate, SubscriptionRowMapper subscriptionRowMapper) { + return new SubscriptionJdbcTemplateRepository(jdbcTemplate, subscriptionRowMapper, linkRowMapper()); + } + + @Bean + public UserRepository userRepository(JdbcTemplate jdbcTemplate, UserRowMapper userRowMapper) { + return new UserJdbcTemplateRepository(jdbcTemplate, userRowMapper); + } + + @Bean + public LinkUpdateService linkUpdateService( + LinkRepository linkRepository, + SubscriptionRepository subscriptionRepository, + Link_Parser linkParser, + GitHubClient gitHubClient, + StackOverflowClient stackOverflowClient, + BotClient botClient + ) { + return new LinkUpdateServiceImpl( + linkRepository, + subscriptionRepository, + linkParser, + gitHubClient, + stackOverflowClient, + botClient); + } + + @Bean + public SubscriptionService subscriptionService( + LinkRepository linkRepository, + SubscriptionRepository subscriptionRepository + ) { + return new SubscriptionServiceImpl( + linkRepository, + subscriptionRepository); + } + + @Bean + public TgChatService tgChatService( + UserRepository userRepository, + SubscriptionRepository subscriptionRepository + ) { + return new TgChatServiceImpl( + userRepository, + subscriptionRepository); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java new file mode 100644 index 0000000..47864de --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java @@ -0,0 +1,84 @@ +package ru.tinkoff.edu.java.scrapper.configuration.database.acess; + +import org.jooq.DSLContext; +import org.jooq.impl.DSL; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.link_parser.Link_Parser; +import ru.tinkoff.edu.java.scrapper.client.BotClient; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; +import ru.tinkoff.edu.java.scrapper.repository.jooq.LinkJooqRepository; +import ru.tinkoff.edu.java.scrapper.repository.jooq.SubscriptionJooqRepository; +import ru.tinkoff.edu.java.scrapper.repository.jooq.UserJooqRepository; +import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; +import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.LinkUpdateServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.SubscriptionServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; +@Configuration +@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jooq") +public class JooqAccessConfiguration { + + + @Bean + public LinkRepository linkRepository(DSLContext dslContext){ + return new LinkJooqRepository(dslContext); + } + + @Bean + public SubscriptionRepository subscriptionRepository(DSLContext dslContext){ + return new SubscriptionJooqRepository(dslContext); + } + + + @Bean + public UserRepository userRepository(DSLContext dslContext){ + return new UserJooqRepository(dslContext); + } + + @Bean + public LinkUpdateService linkUpdateService( + LinkRepository linkRepository, + SubscriptionRepository subscriptionRepository, + LinkParser linkParser, + GitHubClient gitHubClient, + StackOverflowClient stackOverflowClient, + BotClient botClient + ) { + return new LinkUpdateServiceImpl( + linkRepository, + subscriptionRepository, + linkParser, + gitHubClient, + stackOverflowClient, + botClient); + } + + @Bean + public SubscriptionService subscriptionService( + LinkRepository linkRepository, + SubscriptionRepository subscriptionRepository + ) { + return new SubscriptionServiceImpl( + linkRepository, + subscriptionRepository); + } + + @Bean + public TgChatService tgChatService( + UserRepository userRepository, + SubscriptionRepository subscriptionRepository + ) { + return new TgChatServiceImpl( + userRepository, + subscriptionRepository); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java new file mode 100644 index 0000000..ff97aba --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java @@ -0,0 +1,61 @@ +package ru.tinkoff.edu.java.scrapper.configuration.database.acess; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.link_parser.Link_Parser; +import ru.tinkoff.edu.java.scrapper.client.BotClient; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; +import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; +import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; +import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaLinkUpdateServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaSubscriptionServiceImpl; +import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaTgChatServiceImpl; + +@Configuration +@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jpa") +public class JpaAccessConfiguration { + + @Bean + public LinkUpdateService linkUpdateService( + JpaLinkRepository linkRepository, + Link_Parser linkParser, + GitHubClient gitHubClient, + StackOverflowClient stackOverflowClient, + BotClient botClient) { + return new JpaLinkUpdateServiceImpl( + linkRepository, + linkParser, + gitHubClient, + stackOverflowClient, + botClient + ); + } + + @Bean + public SubscriptionService subscriptionService( + JpaLinkRepository linkRepository, + JpaUserRepository userRepository) { + return new JpaSubscriptionServiceImpl( + linkRepository, + userRepository + ); + } + + @Bean + public TgChatService tgChatService( + JpaUserRepository userRepository) { + return new JpaTgChatServiceImpl( + userRepository + ); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java new file mode 100644 index 0000000..97985ba --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +public record AddLinkRequest(String link) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java new file mode 100644 index 0000000..7c065be --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +public record ApiErrorResponse(String description, String code, String exceptionName, + String exceptionMessage, String[] stacktrace) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java new file mode 100644 index 0000000..8f6367c --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java @@ -0,0 +1,25 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.OffsetDateTime; + +public record GitHubResponse(@JsonProperty("pushed") OffsetDateTime pushedAt, + @JsonProperty("updated") OffsetDateTime updatedAt, + @JsonProperty("full_name") String fullName, + @JsonProperty("description") String description, + @JsonProperty("forks_count") int forksCount +) { + + +@Override +public String toString() { + return "GitHubResponse{" + + "pushedAt=" + pushedAt + + ", updatedAt=" + updatedAt + + ", fullName='" + fullName + '\'' + + ", description='" + description + '\'' + + ", forksCount=" + forksCount + + '}'; +} + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java new file mode 100644 index 0000000..cadc95f --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +public record LinkResponse(long id, String url) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java new file mode 100644 index 0000000..1b6410a --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +public record LinkUpdate(Long id, String url, String description, Long[] tgChatIds) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java new file mode 100644 index 0000000..a142f3a --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +import ru.tinkoff.edu.java.scrapper.model.Link; +import java.util.List; + +public record ListLinkResponse(List links, int size) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java new file mode 100644 index 0000000..09a3867 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +public record RemoveLinkRequest(String link) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java new file mode 100644 index 0000000..9e2f0b9 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.scrapper.dto; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.OffsetDateTime; +public record StackOverflowItem(@JsonProperty("last_edit_date") OffsetDateTime lastActivityDate, + @JsonProperty("last_activity_date") OffsetDateTime lastEditDate) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java new file mode 100644 index 0000000..50227fc --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.scrapper.dto; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.OffsetDateTime; +import java.util.List; +public record StackOverflowResponse(List items) { + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java new file mode 100644 index 0000000..58d769c --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.scrapper.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record UserAddDto(@JsonProperty("username") String username, + @JsonProperty("first_name") String firstName, + @JsonProperty("last_name") String lastName) { +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java new file mode 100644 index 0000000..d5be7a4 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class BadResponseFromApiException extends RuntimeException { + + public BadResponseFromApiException() { + } + + public BadResponseFromApiException(String message) { + super(message); + } + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java new file mode 100644 index 0000000..9ee4d12 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class BotClientException extends RuntimeException{ + + public BotClientException() { + } + + public BotClientException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java new file mode 100644 index 0000000..5dd1124 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class ChatAlreadyExistException extends RuntimeException { + + public ChatAlreadyExistException() { + } + + public ChatAlreadyExistException(String message) { + super(message); + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java new file mode 100644 index 0000000..29dc8cf --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class ChatNotFoundException extends RuntimeException { + + public ChatNotFoundException(String message) { + super(message); + } + + public ChatNotFoundException() { + } + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java new file mode 100644 index 0000000..9bf30c3 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class GitHubRequestException extends RuntimeException{ + + public GitHubRequestException() { + } + + public GitHubRequestException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java new file mode 100644 index 0000000..58a7dfb --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class LinkIsAlreadyAddedException extends RuntimeException { + + + public LinkIsAlreadyAddedException(String message) { + super(message); + } + + public LinkIsAlreadyAddedException() { + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java new file mode 100644 index 0000000..e5c5c62 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class LinkNotFoundException extends RuntimeException { + + public LinkNotFoundException() { + } + + public LinkNotFoundException(String message) { + super(message); + } + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java new file mode 100644 index 0000000..e714110 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exception; + +public class StackOverflowRequestException extends RuntimeException{ + + public StackOverflowRequestException() { + super(); + } + + public StackOverflowRequestException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java new file mode 100644 index 0000000..72df1e2 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java @@ -0,0 +1,27 @@ +package ru.tinkoff.edu.java.scrapper.mapper; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.scrapper.model.Link; +import ru.tinkoff.edu.java.scrapper.model.User; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@Component +public class LinkRowMapper implements RowMapper { + + @Override + public Link mapRow(ResultSet rs, int rowNum) throws SQLException { + Link link = new Link(); + link.setId(rs.getLong("id")); + link.setUrl(rs.getString("url")); + link.setCheckedAt(rs.getTimestamp("checked_at")); + link.setGhPushedAt(rs.getTimestamp("gh_pushed_at")); + link.setGhDescription(rs.getString("gh_description")); + link.setGhForksCount(rs.getInt("gh_forks_count")); + link.setSoAnswerCount(rs.getInt("so_answer_count")); + link.setSoLastEditDate(rs.getTimestamp("so_last_edit_date")); + return link; + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java new file mode 100644 index 0000000..bd76b2b --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.scrapper.mapper; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.scrapper.model.Relation; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Component +public class SubscriptionRowMapper implements RowMapper { + + @Override + public Relation mapRow(ResultSet rs, int rowNum) throws SQLException { + Relation relation = new Relation(); + relation.setLinkId(rs.getLong("link_id")); + relation.setChatId(rs.getLong("chat_id")); + + return relation; + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java new file mode 100644 index 0000000..4597040 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java @@ -0,0 +1,24 @@ +package ru.tinkoff.edu.java.scrapper.mapper; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.scrapper.model.User; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +@Component +public class UserRowMapper implements RowMapper { + + + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = new User(); + user.setChatId(rs.getLong("chat_id")); + user.setUsername(rs.getString("username")); + user.setFirstName(rs.getString("first_name")); + user.setLastName(rs.getString("last_name")); + return user; + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java new file mode 100644 index 0000000..59b4a92 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java @@ -0,0 +1,31 @@ +package ru.tinkoff.edu.java.scrapper.model.commonDto; + +import lombok.Data; +import java.sql.Timestamp; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; + +@Data +public class Link { + + + private Long id; + private String url; + private Timestamp checkedAt; + private Timestamp ghPushedAt; + private String ghDescription; + private int ghForksCount; + private Timestamp soLastEditDate; + private int soAnswerCount; + public static Link fromEntity(LinkEntity linkEntity){ + Link link = new Link(); + link.setId(linkEntity.getId()); + link.setUrl(linkEntity.getUrl()); + link.setCheckedAt(linkEntity.getCheckedAt()); + link.setGhDescription(linkEntity.getGhDescription()); + link.setGhPushedAt(linkEntity.getGhPushedAt()); + Integer forks = linkEntity.getGhForksCount(); if (forks == null) link.setGhForksCount(0); else link.setGhForksCount(forks); + Integer answers = linkEntity.getSoAnswerCount(); if (answers == null) link.setSoAnswerCount(0); else link.setSoAnswerCount(answers); + link.setSoLastEditDate(linkEntity.getSoLastEditDate()); + return link; + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java new file mode 100644 index 0000000..74f7693 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java @@ -0,0 +1,32 @@ +package ru.tinkoff.edu.java.scrapper.model.commonDto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; + +@Data +@NoArgsConstructor +public class User { + + public User(Long chatId, String username, String firstName, String lastName) { + this.chatId = chatId; + this.username = username; + this.firstName = firstName; + this.lastName = lastName; + } + + private Long chatId; + private String username; + private String firstName; + private String lastName; + public static UserEntity toEntity(User user){ + UserEntity userEntity = new UserEntity(); + + userEntity.setChatId(user.getChatId()); + userEntity.setUsername(user.getUsername()); + userEntity.setFirstName(user.getFirstName()); + userEntity.setLastName(user.getLastName()); + + return userEntity; + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java new file mode 100644 index 0000000..abe684a --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq; + +import lombok.Data; + +@Data +public class Relation { + + private Long linkId; + private Long chatId; + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java new file mode 100644 index 0000000..bd4469b --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java @@ -0,0 +1,40 @@ +package ru.tinkoff.edu.java.scrapper.model.jpa; + +import jakarta.persistence.*; +import lombok.Data; +import java.sql.Timestamp; +import java.util.List; + +@Entity +@Table(name = "link") +@Data +public class LinkEntity { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "url", unique = true, nullable = false) + private String url; + + @Column(name = "checked_at", nullable = false) + private Timestamp checkedAt; + + @Column(name = "gh_pushed_at") + private Timestamp ghPushedAt; + + @Column(name = "gh_description") + private String ghDescription; + + @Column(name = "gh_forks_count") + private Integer ghForksCount; + + @Column(name = "so_last_edit_date") + private Timestamp soLastEditDate; + + @Column(name = "so_answer_count") + private Integer soAnswerCount; + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java new file mode 100644 index 0000000..8f49d40 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java @@ -0,0 +1,30 @@ +package ru.tinkoff.edu.java.scrapper.model.jpa; + +import jakarta.persistence.*; +import lombok.Data; +import java.util.List; + +@Entity +@Table(name = "\"user\"") +@Data +public class UserEntity { + + @Id + @Column(name = "chat_id") + private Long chatId; + + @Column(name = "username", unique = true, nullable = false) + private String username; + + @Column(name = "first_name") + private String firstName; + + @Column(name = "last_name") + private String lastName; + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "user_link", + joinColumns = @JoinColumn(name = "chat_id"), + inverseJoinColumns = @JoinColumn(name = "link_id")) + private List links; +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java new file mode 100644 index 0000000..38d0931 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java @@ -0,0 +1,86 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbc; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.repository.LinkRepository; + +import java.sql.Timestamp; +import java.util.List; + +@Slf4j +public class LinkJdbcTemplateRepository implements LinkRepository { + + + private final JdbcTemplate jdbcTemplate; + + private final LinkRowMapper linkRowMapper; + + public LinkJdbcTemplateRepository(JdbcTemplate jdbcTemplate, LinkRowMapper linkRowMapper) { + this.jdbcTemplate = jdbcTemplate; + this.linkRowMapper = linkRowMapper; + } + + + @Override + public List findAll() { + log.info("findAll() method invocation in linkRepo"); + String sql = "select * from link"; + return jdbcTemplate.query(sql, linkRowMapper); + } + + @Override + public Link findByUrl(String url) { + log.info("findByUrl() method invocation in linkRepo"); + String sql = "select * from link where link.url = ?"; + List link = jdbcTemplate.query(sql, linkRowMapper, url); + return link.size() == 0 ? null : link.get(0); + } + + @Override + public void add(Link link) { + log.info("add() method invocation in linkRepo"); + String sql = "insert into link (url, updated_at) values(?, ?)"; + jdbcTemplate.update(sql, link.getUrl(), link.getUpdatedAt()); + } + + + @Override + public void updateDate(Link link) { + log.info("updateDate() method invocation in linkRepo"); + String sql = "update link set updated_at = ? where id = ?"; + jdbcTemplate.update(sql, link.getUpdatedAt(), link.getId()); + } + + @Override + public void remove(Long id) { + log.info("remove() method invocation in linkRepo"); + String sql = "delete from link where link.id = ?"; + jdbcTemplate.update(sql, id); + } + + @Override + //поиск ссылок ΠΏΠΎ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ + public List findOldLinks(Long timeUpdateDelta) { + log.info("findOldLinks() method invocation in linkRepo"); + Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDelta*1000); + String sql = "select * from link where link.updated_at < ? order by link.updated_at desc"; + return jdbcTemplate.query(sql,linkRowMapper,compareDate); + } + @Override + public void updateGhLink(Link link) { + log.info("updateGhLink() method invocation in linkJdbcRepo"); + String sql = "update link set gh_forks_count = ?, gh_description = ?, gh_pushed_at = ? where id = ?"; + jdbcTemplate.update(sql, link.getGhForksCount(), link.getGhDescription(), link.getGhPushedAt(), link.getId()); + } + + @Override + public void updateSoLink(Link link) { + log.info("updateSoLastEditDate() method invocation in linkJdbcRepo"); + String sql = "update link set so_last_edit_date = ?, so_answer_count = ? where id = ?"; + jdbcTemplate.update(sql, link.getSoLastEditDate(), link.getSoAnswerCount(), link.getId()); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java new file mode 100644 index 0000000..fce7af7 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java @@ -0,0 +1,75 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbc; + + +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; +import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; +import ru.tinkoff.edu.java.scrapper.model.Link; +import ru.tinkoff.edu.java.scrapper.model.Relation; +import ru.tinkoff.edu.java.scrapper.model.User; +import ru.tinkoff.edu.java.scrapper.repository.SubscriptionRepository; + +import java.util.List; + +@Repository +@Slf4j +public class SubscriptionJdbcTemplateRepository implements SubscriptionRepository { + + private final JdbcTemplate jdbcTemplate; + + private final SubscriptionRowMapper subscriptionRowMapper; + + private final LinkRowMapper linkRowMapper; + + public SubscriptionJdbcTemplateRepository(JdbcTemplate jdbcTemplate, SubscriptionRowMapper subscriptionRowMapper, LinkRowMapper linkRowMapper) { + this.jdbcTemplate = jdbcTemplate; + this.subscriptionRowMapper = subscriptionRowMapper; + this.linkRowMapper = linkRowMapper; + } + + @Override + public List findLinksByChat(Long chatId) { + log.info("findLinksByChat() method invocation in subscriptionRepo"); + String sql = "select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?"; + return jdbcTemplate.query(sql, linkRowMapper, chatId); + } + + @Override + public List findChatsByLink(Long linkId) { + log.info("findChatsByLink() method invocation in subscriptionRepo"); + String sql = "select * from user_link where user_link.link_id = ?"; + return jdbcTemplate.query(sql, subscriptionRowMapper, linkId); + } + + @Override + public Relation findSubscription(Long linkId, Long chatId) { + log.info("findSubscription() method invocation in subscriptionRepo"); + String sql = "select * from user_link rel where rel.chat_id = ? and rel.link_id = ?"; + List relation = jdbcTemplate.query(sql, subscriptionRowMapper, chatId, linkId); + return relation.size() == 0 ? null : relation.get(0); + } + + + @Override + public void addRelation(Relation relation) { + log.info("addRelation() method invocation in subscriptionRepo"); + String sql = "insert into user_link (link_id, chat_id) values(?, ?)"; + jdbcTemplate.update(sql, relation.getLinkId(), relation.getChatId()); + } + + @Override + public void remove(Long linkId, Long chatId) { + log.info("remove() method invocation in subscriptionRepo"); + String sql = "delete from user_link where user_link.link_id = ? and user_link.chat_id = ?"; + jdbcTemplate.update(sql, linkId, chatId); + } + + @Override + public void removeAllByUser(Long chatId) { + log.info("removeAllByUser() method invocation in subscriptionRepo"); + String sql = "delete from user_link where user_link.chat_id = ?"; + jdbcTemplate.update(sql, chatId); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java new file mode 100644 index 0000000..d59d09c --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java @@ -0,0 +1,59 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbc; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; +import ru.tinkoff.edu.java.scrapper.model.User; +import ru.tinkoff.edu.java.scrapper.repository.UserRepository; + +import java.util.List; + +@Repository +@Slf4j +public class UserJdbcTemplateRepository implements UserRepository { + + + private final JdbcTemplate jdbcTemplate; + + private final UserRowMapper userRowMapper; + + + public UserJdbcTemplateRepository(JdbcTemplate jdbcTemplate, UserRowMapper userRowMapper) { + this.jdbcTemplate = jdbcTemplate; + this.userRowMapper = userRowMapper; + } + + @Override + public List findAll(){ + log.info("findAll() method invocation in userRepo"); + String sql = "select * from \"user\""; + return jdbcTemplate.query(sql, userRowMapper); + } + + @Override + public User findByChatId(Long id) { + log.info("findByChatId() method invocation in userRepo"); + String sql = "select * from \"user\" where \"user\".chat_id = ?"; + List user = jdbcTemplate.query(sql, userRowMapper, id); + return user.size() == 0 ? null : user.get(0); + } + + @Override + public void add(User user){ + log.info("add() method invocation in userRepo"); + String sql = "insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)"; + jdbcTemplate.update(sql, user.getChatId(), user.getUsername(), user.getFirstName(), user.getLastName()); + } + + @Override + public void remove(Long chatId){ + log.info("remove() method invocation in userRepo"); + String sql = "delete from \"user\" where \"user\".chat_id = ?"; + jdbcTemplate.update(sql,chatId); + } + + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java new file mode 100644 index 0000000..0298278 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java @@ -0,0 +1,21 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import java.util.List; + + +public interface LinkRepository { + List findAll(); + + + Link findByUrl(String url); + void add(Link link); + + void updateCheckDate(Link link); + void remove(Long id); + List findOldLinks(Long timeUpdateDeltaInSeconds); + + void updateGhLink(Link link); + + void updateSoLink(Link link); +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java new file mode 100644 index 0000000..0dde7e4 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java @@ -0,0 +1,19 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; + +import java.util.List; + +public interface SubscriptionRepository { + + List findLinksByChat(Long chatId); + + List findChatsByLink(Long linkId); + + Relation findSubscription(Long linkId, Long chatId); + void addRelation(Relation relation); + void remove(Long linkId, Long chatId); + + void removeAllByUser(Long chatId); +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java new file mode 100644 index 0000000..87cbf34 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java @@ -0,0 +1,13 @@ +package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; +import java.util.List; + +public interface UserRepository { + List findAll(); + + User findByChatId(Long id); + void add(User user); + void remove(Long id); + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java new file mode 100644 index 0000000..7371ffd --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java @@ -0,0 +1,98 @@ +package ru.tinkoff.edu.java.scrapper.repository.jooq; + +import lombok.extern.slf4j.Slf4j; +import org.jooq.DSLContext; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; +import java.sql.Timestamp; +import java.util.List; +import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.Link.*; + +@Slf4j +public class LinkJooqRepository implements LinkRepository { + + + private final DSLContext dslContext; + + + + public LinkJooqRepository(DSLContext dslContext) { + this.dslContext = dslContext; + } + + @Override + public List findAll() { + log.info("findAll() method invocation in linkJooqRepo"); + return dslContext.selectFrom(LINK) + .fetchInto(Link.class); + } + + @Override + public Link findByUrl(String url) { + log.info("findByUrl() method invocation in linkJooqRepo"); + return dslContext.selectFrom(LINK) + .where(LINK.URL.eq(url)) + .fetchOneInto(Link.class); + } + + @Override + public void add(Link link) { + log.info("add() method invocation in linkJooqRepo"); + dslContext.insertInto(LINK) + .set(LINK.URL, link.getUrl()) + .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) + .execute(); + } + + @Override + public void updateCheckDate(Link link) { + log.info("updateDate() method invocation in linkJooqRepo"); + dslContext.update(LINK) + .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) + .where(LINK.ID.eq(link.getId())) + .execute(); + } + + @Override + public void remove(Long id) { + log.info("remove() method invocation in linkJooqRepo"); + dslContext.deleteFrom(LINK) + .where(LINK.ID.eq(id)) + .execute(); + } + + @Override + public List findOldLinks(Long timeUpdateDeltaInSeconds) { + log.info("findOldLinks() method invocation in linkJooqRepo"); + Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds * 1000); + return dslContext.selectFrom(LINK) + .where(LINK.CHECKED_AT.lessThan(compareDate.toLocalDateTime())) + .orderBy(LINK.CHECKED_AT.desc()) + .fetchInto(Link.class); + } + + @Override + public void updateGhLink(Link link) { + log.info("updateGhLink() method invocation in linkJooqRepo"); + dslContext.update(LINK) + .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) + .set(LINK.GH_FORKS_COUNT, link.getGhForksCount()) + .set(LINK.GH_DESCRIPTION, link.getGhDescription()) + .set(LINK.GH_PUSHED_AT, link.getGhPushedAt().toLocalDateTime()) + .where(LINK.ID.eq(link.getId())) + .execute(); + } + + @Override + public void updateSoLink(Link link) { + log.info("updateSoLink() method invocation in linkJooqRepo"); + dslContext.update(LINK) + .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) + .set(LINK.SO_LAST_EDIT_DATE, link.getSoLastEditDate().toLocalDateTime()) + .set(LINK.SO_ANSWER_COUNT, link.getSoAnswerCount()) + .where(LINK.ID.eq(link.getId())) + .execute(); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java new file mode 100644 index 0000000..6463de4 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java @@ -0,0 +1,80 @@ +package ru.tinkoff.edu.java.scrapper.repository.jooq; + +import lombok.extern.slf4j.Slf4j; +import org.jooq.DSLContext; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.model.Link; +import ru.tinkoff.edu.java.scrapper.model.Relation; +import ru.tinkoff.edu.java.scrapper.repository.SubscriptionRepository; + +import java.util.List; + +import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.UserLink.*; +import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.Link.*; + + +@Repository +@Slf4j +public class SubscriptionJooqRepository implements SubscriptionRepository { + + + private final DSLContext dslContext; + + + public SubscriptionJooqRepository(DSLContext dslContext) { + this.dslContext = dslContext; + } + + + @Override + public List findLinksByChat(Long chatId) { + log.info("findLinksByChat() method invocation in subscriptionJooqRepo"); + return dslContext.select() + .from(LINK) + .join(USER_LINK).on(LINK.ID.eq(USER_LINK.LINK_ID)) + .where(USER_LINK.CHAT_ID.eq(chatId)) + .fetchInto(Link.class); + } + + @Override + public List findChatsByLink(Long linkId) { + log.info("findChatsByLink() method invocation in subscriptionJooqRepo"); + return dslContext.select() + .from(USER_LINK) + .where(USER_LINK.LINK_ID.eq(linkId)) + .fetchInto(Relation.class); + } + + @Override + public Relation findSubscription(Long linkId, Long chatId) { + log.info("findSubscription() method invocation in subscriptionJooqRepo"); + return dslContext.select() + .from(USER_LINK) + .where(USER_LINK.CHAT_ID.eq(chatId).and(USER_LINK.LINK_ID.eq(linkId))) + .fetchOneInto(Relation.class); + } + + @Override + public void addRelation(Relation relation) { + log.info("addRelation() method invocation in subscriptionJooqRepo"); + dslContext.insertInto(USER_LINK, USER_LINK.LINK_ID, USER_LINK.CHAT_ID) + .values(relation.getLinkId(), relation.getChatId()) + .execute(); + } + + @Override + public void remove(Long linkId, Long chatId) { + log.info("remove() method invocation in subscriptionJooqRepo"); + dslContext.deleteFrom(USER_LINK) + .where(USER_LINK.LINK_ID.eq(linkId).and(USER_LINK.CHAT_ID.eq(chatId))) + .execute(); + } + + @Override + public void removeAllByUser(Long chatId) { + log.info("removeAllByUser() method invocation in subscriptionJooqRepo"); + dslContext.deleteFrom(USER_LINK) + .where(USER_LINK.CHAT_ID.eq(chatId)) + .execute(); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java new file mode 100644 index 0000000..d942314 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java @@ -0,0 +1,59 @@ +package ru.tinkoff.edu.java.scrapper.repository.jooq; + +import lombok.extern.slf4j.Slf4j; +import org.jooq.DSLContext; +import org.springframework.stereotype.Repository; +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; +import java.util.List; + +import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.User.*; + +@Repository +@Slf4j +public class UserJooqRepository implements UserRepository { + + private final DSLContext dslContext; + + + public UserJooqRepository(DSLContext dslContext) { + this.dslContext = dslContext; + } + + @Override + public List findAll() { + log.info("findAll() method invocation in userJooqRepo"); + + return dslContext.selectFrom(USER).fetchInto(User.class); + } + + @Override + public User findByChatId(Long id) { + log.info("findByChatId() method invocation in userJooqRepo"); + + return dslContext.selectFrom(USER) + .where(USER.CHAT_ID.eq(id)) + .fetchOneInto(User.class); + } + + @Override + public void add(User user) { + log.info("add() method invocation in userJooqRepo"); + + dslContext.insertInto(USER) + .set(USER.CHAT_ID, user.getChatId()) + .set(USER.USERNAME, user.getUsername()) + .set(USER.FIRST_NAME, user.getFirstName()) + .set(USER.LAST_NAME, user.getLastName()) + .execute(); + } + + @Override + public void remove(Long chatId) { + log.info("remove() method invocation in userJooqRepo"); + + dslContext.deleteFrom(USER) + .where(USER.CHAT_ID.eq(chatId)) + .execute(); + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java new file mode 100644 index 0000000..2f1dab8 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.scrapper.repository.jpa; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; + +import java.sql.Timestamp; +import java.util.List; +import java.util.Optional; + +public interface JpaLinkRepository extends JpaRepository { + Optional findByUrl(String url); + + @Query("select u.chatId from UserEntity u join u.links l where l.id = :id") + List findChatIdsByLinkId(@Param("id") Long id); + + List findByCheckedAtLessThanOrderByCheckedAtDesc(Timestamp compareDate); + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java new file mode 100644 index 0000000..cdcb762 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java @@ -0,0 +1,22 @@ +package ru.tinkoff.edu.java.scrapper.repository.jpa; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; +import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; + +import java.util.List; +import java.util.Optional; + +public interface JpaUserRepository extends JpaRepository { + + @Query("select link from UserEntity u join u.links link where u.chatId = :chatId") + List findAllLinksByChat(@Param("chatId") Long chatId); + + + @Query("select u from UserEntity u join fetch u.links link where u.chatId = :chatId") + Optional findByChatIdWithLinks(@Param("chatId") Long chatId); + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java new file mode 100644 index 0000000..388ebac --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java @@ -0,0 +1,30 @@ +package ru.tinkoff.edu.java.scrapper.rest; + +import org.springframework.web.bind.annotation.*; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; +import ru.tinkoff.edu.java.scrapper.dto.UserAddDto; +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; + +@RestController +@RequestMapping("/tg-chat") +public class ChatRestController { + + + private final TgChatService chatService; + + public ChatRestController(TgChatService chatService) { + this.chatService = chatService; + } + + @PostMapping(value = "{id}") + public void registerChat(@PathVariable Long id, @RequestBody UserAddDto userAddDto) { + chatService.register(new User(id, userAddDto.username(), userAddDto.firstName(), userAddDto.lastName())); + } + + @DeleteMapping(value = "{id}") + public void deleteChat(@PathVariable Long id) { + chatService.unregister(id); + } + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java new file mode 100644 index 0000000..5aef3ac --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java @@ -0,0 +1,44 @@ +package ru.tinkoff.edu.java.scrapper.rest; + +import org.springframework.web.bind.annotation.*; +import ru.tinkoff.edu.java.scrapper.dto.AddLinkRequest; +import ru.tinkoff.edu.java.scrapper.dto.LinkResponse; +import ru.tinkoff.edu.java.scrapper.dto.ListLinkResponse; +import ru.tinkoff.edu.java.scrapper.dto.RemoveLinkRequest; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkService; +import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; +import java.net.URI; +import java.util.List; + +@RestController +@RequestMapping("/links") +public class LinkRestController { + + private final SubscriptionService subscriptionService; + + public LinkRestController(SubscriptionService subscriptionService) { + this.subscriptionService = subscriptionService; + } + + @GetMapping + public ListLinkResponse getLinks(@RequestHeader("Tg-Chat-Id") Long chatId) { + List list = subscriptionService.getLinksByChat(chatId); + return new ListLinkResponse(list, list.size()); + } + + @PostMapping + public LinkResponse addLink(@RequestHeader("Tg-Chat-Id") Long chatId, @RequestBody AddLinkRequest request) { + Link link = subscriptionService.subscribe(chatId, URI.create(request.link())); + return new LinkResponse(link.getId(), link.getUrl()); + } + + @DeleteMapping + public LinkResponse deleteLink(@RequestHeader("Tg-Chat-Id") Long chatId, @RequestBody RemoveLinkRequest request) { + Link link = subscriptionService.unsubscribe(chatId, URI.create(request.link())); + if (link == null) throw new LinkNotFoundException("Бсылка с Ρ‚Π°ΠΊΠΈΠΌ url Π½Π΅ отслСТиваСтся!"); + return new LinkResponse(link.getId(), link.getUrl()); + } + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java new file mode 100644 index 0000000..eec99f7 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.scrapper.schedule; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; + +import java.util.List; + +@Slf4j +@Component +public class LinkUpdateScheduler { + + private final LinkUpdateService linkUpdateService; + + + public LinkUpdateScheduler(LinkUpdateService linkUpdateService, Parser_Link linkParser) { + this.linkUpdateService = linkUpdateService; + } + + @Scheduled(fixedDelayString = "#{@schedulerIntervalMs}") + public void update() { + log.info("update() method invocation in LinkUpdateScheduler"); + linkUpdateService.updateLinks(); + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java new file mode 100644 index 0000000..623f12b --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.scrapper.schedule; + +import java.time.Duration; + +public record Scheduler(Duration interval) { +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java new file mode 100644 index 0000000..91471de --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.scrapper.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.core.AmqpTemplate; +import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; +import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; + +@Slf4j +//Π±ΠΈΠ½ рСгистрируСтся Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅, Ρ‚.ΠΊ. Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² случаС общСния ΠΏΠΎ HTTP +public class ScrapperQueueProducer implements UpdateNotificationService { + + private final AmqpTemplate rabbitTemplate; + + private final ApplicationConfig config; + + + public ScrapperQueueProducer(AmqpTemplate rabbitTemplate, ApplicationConfig config) { + this.rabbitTemplate = rabbitTemplate; + this.config = config; + } + + public void updateLink(LinkUpdate update) { + rabbitTemplate.convertAndSend(config.exchangeName(), config.routingKey(), update); + log.info("UpdateMessage " + update + " has been sent"); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java new file mode 100644 index 0000000..61ee96d --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java @@ -0,0 +1,8 @@ +package ru.tinkoff.edu.java.scrapper.service; + +import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; + +public interface UpdateNotificationService { + + void updateLink(LinkUpdate request); +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java new file mode 100644 index 0000000..10646d7 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.service.contract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import java.util.List; + +public interface LinkUpdateService { + + + List getOldLinks(); + + void updateLinks(); +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java new file mode 100644 index 0000000..b35caad --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java @@ -0,0 +1,14 @@ +package ru.tinkoff.edu.java.scrapper.service.contract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import java.net.URI; +import java.util.List; + +public interface SubscriptionService { + + Link add(Long chatId, URI url); + Link remove(Long chatId, URI url); + + List getAllByUser(Long chatId); + +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java new file mode 100644 index 0000000..adf1fde --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.service.contract; + +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; + +public interface TgChatService { + + void register(User user); + + void unregister(Long chatId); + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java new file mode 100644 index 0000000..983fdb9 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java @@ -0,0 +1,156 @@ +package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; +import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; +import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; +import ru.tinkoff.edu.java.scrapper.client.BotClient; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; +import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; +import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; +import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; +import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; +//import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +//import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; +//import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; +//import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +//import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; + +import java.sql.Timestamp; +import java.time.ZoneOffset; +import java.util.List; + +@Slf4j +public class LinkUpdateServiceImpl implements LinkUpdateService { + + + @Value("${update.delta.time}") + private Long timeUpdateDeltaInSeconds; + + private final LinkRepository linkRepository; + + private final SubscriptionRepository subscriptionRepository; + + private final Link_Parser linkParser; + + private final GitHubClient gitHubClient; + + private final StackOverflowClient stackOverflowClient; + + private final BotClient botClient; + + + public LinkUpdateServiceImpl(LinkRepository linkRepository, SubscriptionRepository subscriptionRepository, Link_Parser linkParser, GitHubClient gitHubClient, StackOverflowClient stackOverflowClient, BotClient botClient) { + this.linkRepository = linkRepository; + this.subscriptionRepository = subscriptionRepository; + this.linkParser = linkParser; + this.gitHubClient = gitHubClient; + this.stackOverflowClient = stackOverflowClient; + this.botClient = botClient; + } + + @Override + public List getOldLinks() { + return linkRepository.findOldLinks(timeUpdateDeltaInSeconds); + } + + + public void updateLinks() { + List oldLinks = getOldLinks(); + + for (Link link : oldLinks) { + Parser_Link result = linkParser.parseUrl(link.getUrl()); + if (result instanceof GitHub_Link) { + try { + boolean isUpdated = false; + String updateDescription = ""; + + + GitHubResponse response = gitHubClient.fetchRepo(((GithubParseResult) result).username(), ((GithubParseResult) result).repository()); + + + if (response.forksCount() != link.getGhForksCount()) { + isUpdated = true; + if (response.forksCount() < link.getGhForksCount()) { + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ„ΠΎΡ€ΠΊΠΎΠ²\n"; + } + if (response.forksCount() > link.getGhForksCount()) { + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появились Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΠΎΡ€ΠΊΠΈ\n"; + } + link.setGhForksCount(response.forksCount()); + } + + + if (link.getGhDescription() == null || !response.description().equals(link.getGhDescription())) { + if (link.getGhDescription() != null) isUpdated = true; + link.setGhDescription(response.description()); + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ измСнилось описаниС\n"; + } + + if (link.getGhPushedAt() == null || response.pushedAt().toInstant().isAfter(link.getGhPushedAt().toInstant())) { + if (link.getGhPushedAt() != null) isUpdated = true; + link.setGhPushedAt(new Timestamp(response.pushedAt().toInstant().toEpochMilli())); + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появился Π½ΠΎΠ²Ρ‹ΠΉ commit\n"; + } + + + linkRepository.updateCheckDate(link); + + if (isUpdated) { + Long[] chats = subscriptionRepository.findChatsByLink(link.getId()).stream().map(Relation::getChatId).toArray(Long[]::new); + botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ:\n"+updateDescription, chats)); + } + + + } catch (GitHubRequestException e) { + log.warn(e.getMessage()); + } + + } else if (result instanceof StackOverflow_Link) { + try { + + boolean isUpdated = false; + String updateDescription = ""; + + + StackOverflowItem response = stackOverflowClient.fetchQuestion(((StackOverflowParseResult) result).id()); + + + if (response.lastEditDate() != null && (link.getSoLastEditDate() == null || response.lastEditDate().isAfter(link.getSoLastEditDate().toLocalDateTime().atOffset(ZoneOffset.UTC)))) { + if (link.getSoLastEditDate() != null) isUpdated = true; + link.setSoLastEditDate(new Timestamp(response.lastEditDate().toInstant().toEpochMilli())); + updateDescription += "ВСкст вопроса Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½\n"; + } + + if (response.answerCount() != link.getSoAnswerCount()) { + isUpdated = true; + if (response.answerCount() < link.getSoAnswerCount()) { + updateDescription += "На вопрос ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²\n"; + } + if (response.answerCount() > link.getSoAnswerCount()) { + updateDescription += "На вопрос появились Π½ΠΎΠ²Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹\n"; + } + link.setSoAnswerCount(response.answerCount()); + } + + linkRepository.updateCheckDate(link); + + if (isUpdated) { + + Long[] chats = subscriptionRepository.findChatsByLink(link.getId()).stream().map(Relation::getChatId).toArray(Long[]::new); + botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² вопросС:\n"+updateDescription, chats)); + } + + } catch (StackOverflowRequestException e) { + log.warn(e.getMessage()); + } + } + } + } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java new file mode 100644 index 0000000..4476e8b --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java @@ -0,0 +1,99 @@ +package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; + +import java.net.URI; +import java.sql.Timestamp; +import java.util.List; + + +@Slf4j +public class SubscriptionServiceImpl implements SubscriptionService { + + + private final LinkRepository linkRepository; + + private final SubscriptionRepository subscriptionRepository; + + + + public SubscriptionServiceImpl(LinkRepository linkRepository, SubscriptionRepository subscriptionRepository) { + this.linkRepository = linkRepository; + this.subscriptionRepository = subscriptionRepository; + } + + @Override + @Transactional + public Link subscribe(Long chatId, URI url) { + log.info("subscribe() method invocation in SubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); + Link link = linkRepository.findByUrl(url.toString()); + if (link == null) { + link = new Link(); + link.setUrl(url.toString()); + link.setCheckedAt(new Timestamp(System.currentTimeMillis())); + linkRepository.add(link); + //ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Π½ΠΈΠΆΠ΅ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ id ΠΈΠ· Π‘Π” + link = linkRepository.findByUrl(link.getUrl()); + } + Relation relation = subscriptionRepository.findSubscription(link.getId(), chatId); + + if (relation == null) { + relation = new Relation(); + relation.setChatId(chatId); + relation.setLinkId(link.getId()); + subscriptionRepository.addRelation(relation); + } + return link; + } + + @Override + @Transactional + public Link unsubscribe(Long chatId, URI url) { + log.info("unsubscribe() method invocation in SubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); + Link link = linkRepository.findByUrl(url.toString()); + + if (link != null) { +// linkRepository.remove(link.getId()); + subscriptionRepository.remove(link.getId(), chatId); + } + return link; + } + + @Override + public List getLinksByChat(Long chatId) { + log.info("getLinksByChat() method invocation in SubscriptionServiceImpl. chatId = "+chatId); + return subscriptionRepository.findLinksByChat(chatId); + } + + @Override + public List getChatIdsByLink(Long linkId) { + log.info("getChatIdsByLink() method invocation in SubscriptionServiceImpl. linkId = "+linkId); + return null; + } + + @Override + public Link add(Long chatId, URI url) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Link remove(Long chatId, URI url) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getAllByUser(Long chatId) { + // TODO Auto-generated method stub + return null; + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java new file mode 100644 index 0000000..84a130a --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java @@ -0,0 +1,42 @@ +package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; + +@Slf4j +public class TgChatServiceImpl implements TgChatService { + + private final UserRepository userRepository; + + private final SubscriptionRepository subscriptionRepository; + + + public TgChatServiceImpl(UserRepository userRepository, SubscriptionRepository subscriptionRepository) { + this.userRepository = userRepository; + this.subscriptionRepository = subscriptionRepository; + } + + @Override + public void register(User user) { + log.info("register() method invocation in TgChatServiceImpl. chatId = "+user.getChatId()); + User userInBd = userRepository.findByChatId(user.getChatId()); + if (userInBd != null) throw new ChatAlreadyExistException(); + userRepository.add(user); + } + + @Override + @Transactional + public void unregister(Long chatId) { + log.info("unregister() method invocation in TgChatServiceImpl. chatId = "+chatId); + userRepository.remove(chatId); + subscriptionRepository.removeAllByUser(chatId); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java new file mode 100644 index 0000000..f27d081 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java @@ -0,0 +1,174 @@ +package ru.tinkoff.edu.java.scrapper.service.jpa.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; +import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; +import ru.tinkoff.edu.java.link_parser.link.Parser_Link; +import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; +import ru.tinkoff.edu.java.scrapper.client.BotClient; +import ru.tinkoff.edu.java.scrapper.client.GitHubClient; +import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; +import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; +import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; +import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; +import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; +import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; +import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; + +import java.sql.Timestamp; +import java.time.ZoneOffset; +import java.util.List; + +@Slf4j +public class JpaLinkUpdateServiceImpl implements LinkUpdateService { + + @Value("${update.delta.time}") + private Long timeUpdateDeltaInSeconds; + + private final JpaLinkRepository linkRepository; + + + + private final Link_Parser linkParser; + + private final GitHubClient gitHubClient; + + private final StackOverflowClient stackOverflowClient; + + private final BotClient botClient; + + + public JpaLinkUpdateServiceImpl(JpaLinkRepository linkRepository, LinkParser linkParser, GitHubClient gitHubClient, StackOverflowClient stackOverflowClient, BotClient botClient) { + this.linkRepository = linkRepository; + this.linkParser = linkParser; + this.gitHubClient = gitHubClient; + this.stackOverflowClient = stackOverflowClient; + this.botClient = botClient; + } + + @Override + public List getOldLinks() { + log.info("getOldLinks() method invocation in JpaLinkUpdateServiceImpl"); + Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds*1000); + return linkRepository.findByCheckedAtLessThanOrderByCheckedAtDesc(compareDate).stream().map(Link::fromEntity).toList(); + } + + + public List getOldEntityLinks() { + Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds*1000); + return linkRepository.findByCheckedAtLessThanOrderByCheckedAtDesc(compareDate); + } + + @Override + @Transactional + public void updateLinks() { + log.info("updateLinks() method invocation in JpaLinkUpdateServiceImpl"); + List oldLinks = getOldEntityLinks(); + + for (LinkEntity link : oldLinks) { + Parser_Link result = linkParser.parseUrl(link.getUrl()); + if (result instanceof GitHub_Link) { + try { + boolean isUpdated = false; + String updateDescription = ""; + + + System.out.println(link.getUrl()); + GitHubResponse response = gitHubClient.fetchRepo(((GitHub_Link) result).username(), ((GithubParseResult) result).repository()); + System.out.println(response); + + + if (link.getGhForksCount() == null || response.forksCount() != link.getGhForksCount()) { + isUpdated = true; + if (link.getGhForksCount() == null) {link.setGhForksCount(0); isUpdated = false;} + if (isUpdated && response.forksCount() < link.getGhForksCount()) { + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ„ΠΎΡ€ΠΊΠΎΠ²\n"; + } + if (isUpdated && response.forksCount() > link.getGhForksCount()) { + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появились Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΠΎΡ€ΠΊΠΈ\n"; + } + link.setGhForksCount(response.forksCount()); + } + + + if (link.getGhDescription() == null || !response.description().equals(link.getGhDescription())) { + if (link.getGhDescription() != null) isUpdated = true; + link.setGhDescription(response.description()); + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ измСнилось описаниС\n"; + } + + if (link.getGhPushedAt() == null || response.pushedAt().toInstant().isAfter(link.getGhPushedAt().toInstant())) { + if (link.getGhPushedAt() != null) isUpdated = true; + link.setGhPushedAt(new Timestamp(response.pushedAt().toInstant().toEpochMilli())); + updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появился Π½ΠΎΠ²Ρ‹ΠΉ commit\n"; + } + + link.setCheckedAt(new Timestamp(System.currentTimeMillis())); + + linkRepository.save(link); + + if (isUpdated) { + List chatsIds = linkRepository.findChatIdsByLinkId(link.getId()); + botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ:\n"+updateDescription, chatsIds.toArray(new Long[0]))); + } + + + } catch (GitHubRequestException e) { + log.warn(e.getMessage()); + } + + } else if (result instanceof StackOverflow_Link) { + try { + + boolean isUpdated = false; + String updateDescription = ""; + + + System.out.println(link.getUrl()); + StackOverflowItem response = stackOverflowClient.fetchQuestion(((StackOverflowParseResult) result).id()); + System.out.println(response); + + + + if (response.lastEditDate() != null && (link.getSoLastEditDate() == null || response.lastEditDate().isAfter(link.getSoLastEditDate().toLocalDateTime().atOffset(ZoneOffset.UTC)))) { + if (link.getSoLastEditDate() != null) isUpdated = true; + link.setSoLastEditDate(new Timestamp(response.lastEditDate().toInstant().toEpochMilli())); + updateDescription += "ВСкст вопроса Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½\n"; + } + + if (link.getSoAnswerCount() == null || response.answerCount() != link.getSoAnswerCount()) { + isUpdated = true; + if (link.getSoAnswerCount() == null) {link.setSoAnswerCount(0); isUpdated = false;} + if (isUpdated && response.answerCount() < link.getSoAnswerCount()) { + updateDescription += "На вопрос ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²\n"; + } + if (isUpdated && response.answerCount() > link.getSoAnswerCount()) { + updateDescription += "На вопрос появились Π½ΠΎΠ²Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹\n"; + } + link.setSoAnswerCount(response.answerCount()); + } + + + link.setCheckedAt(new Timestamp(System.currentTimeMillis())); + + linkRepository.save(link); + + if (isUpdated) { + List chatsIds = linkRepository.findChatIdsByLinkId(link.getId()); + botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² вопросС:\n"+updateDescription, chatsIds.toArray(new Long[0]))); + } + + } catch (StackOverflowRequestException e) { + log.warn(e.getMessage()); + } + } + } + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java new file mode 100644 index 0000000..c5c9749 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java @@ -0,0 +1,100 @@ +package ru.tinkoff.edu.java.scrapper.service.jpa.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; +import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; +import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; +import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; +import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; +import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; + +import java.net.URI; +import java.sql.Timestamp; +import java.util.List; +import java.util.Optional; + +@Slf4j +public class JpaSubscriptionServiceImpl implements SubscriptionService { + + private final JpaLinkRepository linkRepository; + + private final JpaUserRepository userRepository; + + public JpaSubscriptionServiceImpl(JpaLinkRepository linkRepository, JpaUserRepository userRepository) { + this.linkRepository = linkRepository; + this.userRepository = userRepository; + } + + + @Override + @Transactional + public Link subscribe(Long chatId, URI url) { + log.info("subscribe() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); + Optional optionalLink = linkRepository.findByUrl(url.toString()); + LinkEntity linkToAdd = new LinkEntity(); + if (optionalLink.isEmpty()) { + linkToAdd.setUrl(url.toString()); + } else { + linkToAdd = optionalLink.get(); + } + linkToAdd.setCheckedAt(new Timestamp(System.currentTimeMillis())); + linkRepository.save(linkToAdd); + + Optional optionalUser = userRepository.findById(chatId); + if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); + UserEntity user = optionalUser.get(); + List userLinks = user.getLinks(); + + if (!userLinks.contains(linkToAdd)) { + userLinks.add(linkToAdd); + } + + userRepository.save(user); + return Link.fromEntity(linkToAdd); + } + + @Override + @Transactional + public Link unsubscribe(Long chatId, URI url) { + log.info("unsubscribe() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); + Optional optionalUser = userRepository.findByChatIdWithLinks(chatId); + Optional optionalLink = linkRepository.findByUrl(url.toString()); + + + if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ зарСгистрирован"); + + UserEntity user = optionalUser.get(); + + List userLinks = user.getLinks(); + + if (optionalLink.isEmpty() || !userLinks.contains(optionalLink.get())) + throw new LinkNotFoundException("Вакая ссылка Π½Π΅ отслСТиваСтся"); + + userLinks.remove(optionalLink.get()); + userRepository.save(user); + + return Link.fromEntity(optionalLink.get()); + } + + @Override + public List getLinksByChat(Long chatId) { + log.info("getAllByUser() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId); + Optional optionalUser = userRepository.findById(chatId); + if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); + return userRepository.findAllLinksByChat(chatId).stream().map(Link::fromEntity).toList(); + } + + + @Override + public List getChatIdsByLink(Long linkId) { + log.info("getChatIdsByLink() method invocation in JpaSubscriptionServiceImpl. linkId = "+linkId); + Optional optionalLink = linkRepository.findById(linkId); + if (optionalLink.isEmpty()) throw new LinkNotFoundException("Вакая ссылка Π½Π΅ отслСТиваСтся"); + return linkRepository.findChatIdsByLinkId(linkId); + } +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java new file mode 100644 index 0000000..b87e274 --- /dev/null +++ b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java @@ -0,0 +1,43 @@ +package ru.tinkoff.edu.java.scrapper.service.jpa.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; +import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; +import ru.tinkoff.edu.java.scrapper.model.commonDto.User; +import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; +import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; +import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; + +import java.util.Optional; + + +@Slf4j +public class JpaTgChatServiceImpl implements TgChatService { + + private final JpaUserRepository userRepository; + + public JpaTgChatServiceImpl(JpaUserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public void register(User user) { + log.info("register() method invocation in JpaTgChatServiceImpl. User chatId = "+user.getChatId()); + Optional optionalUser = userRepository.findById(user.getChatId()); + if (optionalUser.isPresent()) throw new ChatAlreadyExistException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ ΡƒΠΆΠ΅ зарСгистрирован!"); + userRepository.save(User.toEntity(user)); + } + + @Override + public void unregister(Long chatId) { + log.info("unregister() method invocation in JpaTgChatServiceImpl. User chatId = "+chatId); + Optional optionalUser = userRepository.findById(chatId); + if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); + userRepository.delete(optionalUser.get()); + } + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/resources/application.properties b/FP/FP/scrapper/src/main/resources/application.properties new file mode 100644 index 0000000..3761f00 --- /dev/null +++ b/FP/FP/scrapper/src/main/resources/application.properties @@ -0,0 +1,23 @@ +server.port=8080 +app.test=beamer-scrapper +gh.baseurl=https://api.github.com +so.baseurl=https://api.stackexchange.com/2.3/ +bot.baseurl=http://localhost:8081 +app.scheduler.interval=61000 +update.delta.time=20 +springdoc.swagger-ui.path=/swagger-ui + +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url=jdbc:postgresql://localhost:5432/scrapper +spring.datasource.username=romanova +spring.datasource.password=12345654321 +spring.jpa.properties.hibernate.show_sql=true + +spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=romanova +spring.rabbitmq.password=12345654321 +app.queue-name=scrapper-bot-queue +app.exchange-name=scrapper-bot-exchange +app.routing-key=scrapper-bot-key +app.use-queue=true diff --git a/FP/FP/scrapper/src/main/resources/logback-test.xml b/FP/FP/scrapper/src/main/resources/logback-test.xml new file mode 100644 index 0000000..900637e --- /dev/null +++ b/FP/FP/scrapper/src/main/resources/logback-test.xml @@ -0,0 +1,17 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + + + +. diff --git a/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java b/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java new file mode 100644 index 0000000..1c2378c --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java @@ -0,0 +1,38 @@ +package scrapper; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.sql.*; + +public class DatabaseTest extends IntegrationEnvironment{ + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° с PostgreSQL") + public void testIfContainerIsRunning() { + Assertions.assertTrue(POSTGRES_CONTAINER.isRunning(),"Ошибка запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° PostgreSQL"); + } + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ примСнСния ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ") + void testMigrations() throws SQLException { + try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), + IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), + IntegrationEnvironment.POSTGRES_CONTAINER.getPassword()); + Statement statement = conn.createStatement()) { + + ResultSet resultSetUser = statement.executeQuery("SELECT * FROM \"user\""); + Assertions.assertFalse(resultSetUser.next(), "Π’Π°Π±Π»ΠΈΡ†Π° user Π½Π΅ создана"); + ResultSet resultSetLink = statement.executeQuery("SELECT * FROM \"link\""); + Assertions.assertFalse(resultSetLink.next(), "Π’Π°Π±Π»ΠΈΡ†Π° link Π½Π΅ создана"); + ResultSet resultSetUserLink = statement.executeQuery("SELECT * FROM \"user_link\""); + Assertions.assertFalse(resultSetUserLink.next(),"Π’Π°Π±Π»ΠΈΡ†Π° user_link Π½Π΅ создана"); + } + } + + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java b/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java new file mode 100644 index 0000000..2f0bdfa --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java @@ -0,0 +1,54 @@ +package scrapper; + +import liquibase.Contexts; +import liquibase.LabelExpression; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.LiquibaseException; +import liquibase.resource.DirectoryResourceAccessor; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +abstract class IntegrationEnvironment { + + static final String IMAGE_VERSION = "postgres:15"; + + static final PostgreSQLContainer POSTGRES_CONTAINER; + + static { + POSTGRES_CONTAINER = new PostgreSQLContainer(IMAGE_VERSION) + .withDatabaseName("scrapper") + .withUsername("lwbeamer") + .withPassword("2281337"); + + + POSTGRES_CONTAINER.start(); + executeMigrations(); + } + + private static void executeMigrations() { + try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), + IntegrationEnvironment.POSTGRES_CONTAINER.getPassword())) { + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); + Path changeLogFile = new File("").toPath().toAbsolutePath().getParent().resolve("migrations"); + Liquibase liquibase = new Liquibase("master.xml",new DirectoryResourceAccessor(changeLogFile), database); + liquibase.update(new Contexts(), new LabelExpression()); + } catch (SQLException | LiquibaseException e) { + throw new RuntimeException("Failed to execute migrations", e); + } catch (FileNotFoundException e) { + throw new RuntimeException("Changelog file not found",e); + } + } + + public static void stopContainer() { + POSTGRES_CONTAINER.stop(); + } diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java b/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java new file mode 100644 index 0000000..d0ac18a --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java @@ -0,0 +1,38 @@ +package scrapper.environment; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.sql.*; + +public class DatabaseTest extends IntegrationEnvironment{ + + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° с PostgreSQL") + public void testIfContainerIsRunning() { + Assertions.assertTrue(POSTGRES_CONTAINER.isRunning(),"Ошибка запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° PostgreSQL"); + } + + @Test + @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ примСнСния ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ") + void testMigrations() throws SQLException { + try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), + IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), + IntegrationEnvironment.POSTGRES_CONTAINER.getPassword()); + Statement statement = conn.createStatement()) { + + ResultSet resultSetUser = statement.executeQuery("SELECT * FROM \"user\""); + Assertions.assertFalse(resultSetUser.next(), "Π’Π°Π±Π»ΠΈΡ†Π° user Π½Π΅ создана"); + ResultSet resultSetLink = statement.executeQuery("SELECT * FROM \"link\""); + Assertions.assertFalse(resultSetLink.next(), "Π’Π°Π±Π»ΠΈΡ†Π° link Π½Π΅ создана"); + ResultSet resultSetUserLink = statement.executeQuery("SELECT * FROM \"user_link\""); + Assertions.assertFalse(resultSetUserLink.next(),"Π’Π°Π±Π»ΠΈΡ†Π° user_link Π½Π΅ создана"); + } + } + + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java b/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java new file mode 100644 index 0000000..416b086 --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java @@ -0,0 +1,81 @@ +package scrapper.environment; + +import liquibase.Contexts; +import liquibase.LabelExpression; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.LiquibaseException; +import liquibase.resource.DirectoryResourceAccessor; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.testcontainers.containers.PostgreSQLContainer; + +import javax.sql.DataSource; +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +@ContextConfiguration(classes = IntegrationEnvironment.EnvironmentConfiguration.class) +public abstract class IntegrationEnvironment { + + + @Configuration + static class EnvironmentConfiguration{ + @Bean + public DataSource dataSource() { + return DataSourceBuilder.create() + .url(POSTGRES_CONTAINER.getJdbcUrl()) + .username(POSTGRES_CONTAINER.getUsername()) + .password(POSTGRES_CONTAINER.getPassword()) + .build(); + } + + @Bean + public JdbcTemplate jdbcTemplate(DataSource dataSource){ + return new JdbcTemplate(dataSource); + } + + } + + static final String IMAGE_VERSION = "postgres:15"; + + static final PostgreSQLContainer POSTGRES_CONTAINER; + + static { + POSTGRES_CONTAINER = new PostgreSQLContainer(IMAGE_VERSION) + .withDatabaseName("scrapper") + .withUsername("lwbeamer") + .withPassword("2281337"); + + + POSTGRES_CONTAINER.start(); + executeMigrations(); + } + + private static void executeMigrations() { + try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), + IntegrationEnvironment.POSTGRES_CONTAINER.getPassword())) { + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); + Path changeLogFile = new File("").toPath().toAbsolutePath().getParent().resolve("migrations"); + Liquibase liquibase = new Liquibase("master.xml",new DirectoryResourceAccessor(changeLogFile), database); + liquibase.update(new Contexts(), new LabelExpression()); + } catch (SQLException | LiquibaseException e) { + throw new RuntimeException("Failed to execute migrations", e); + } catch (FileNotFoundException e) { + throw new RuntimeException("Changelog file not found",e); + } + } + + public static void stopContainer() { + POSTGRES_CONTAINER.stop(); + } + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java b/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java new file mode 100644 index 0000000..a4ff395 --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java @@ -0,0 +1,8 @@ +package scrapper.environment; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; + +@EnableAutoConfiguration(exclude = { LiquibaseAutoConfiguration.class }) +public class TestConfiguration { +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java new file mode 100644 index 0000000..436f01a --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java @@ -0,0 +1,151 @@ +package scrapper.jdbc; + +import scrapper.environment.IntegrationEnvironment; +import scrapper.environment.TestConfiguration; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.Rollback; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.ScrapperApplication; +import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; +import ru.tinkoff.edu.java.scrapper.model.Link; +import ru.tinkoff.edu.java.scrapper.repository.*; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; + +import java.sql.Timestamp; +import java.util.List; + +@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) +public class JdbcLinkTest extends IntegrationEnvironment { + + @Autowired + private LinkJdbcTemplateRepository linkRepository; + + @Autowired + private LinkRowMapper linkRowMapper; + + @Autowired + private JdbcTemplate jdbcTemplate; + + + @Test + @Transactional + @Rollback + public void addLinkTest() { + List beforeAddLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); + + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + linkRepository.add(linkToAdd); + + List addedLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertNotNull(addedLink.get(0)); + Assertions.assertEquals("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file", addedLink.get(0).getUrl()); + } + + + @Test + @Transactional + @Rollback + public void removeLinkTest() { + List beforeAddLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); + + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + + List afterInsertionLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); + + linkRepository.remove(afterInsertionLink.get(0).getId()); + + List afterRemovingLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); + + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 1); + Assertions.assertEquals(afterRemovingLink.size(), 0); + } + + + @Test + @Transactional + @Rollback + public void findAllTest() { + List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); + + for (int i = 0; i < 10; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = linkRepository.findAll(); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 10); + } + + + @Test + @Transactional + @Rollback + public void findByUrlTest(){ + List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); + + for (int i = 0; i < 10; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + Link foundedByUrlLink = linkRepository.findByUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file0"); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 10); + Assertions.assertNotNull(foundedByUrlLink); + } + + + @Test + @Transactional + @Rollback + public void updateDateTest(){ + List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); + + + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); + linkToAdd.setUpdatedAt(timestampBefore); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + + + List linkBeforeUpdate = jdbcTemplate.query("select * from link where link.url = ?", linkRowMapper, "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + + Assertions.assertEquals(linkBeforeUpdate.get(0).getUpdatedAt(),timestampBefore); + + linkBeforeUpdate.get(0).setUpdatedAt(new Timestamp(100000)); + + linkRepository.updateDate(linkBeforeUpdate.get(0)); + + List linkAfterUpdate = jdbcTemplate.query("select * from link where link.url = ?", linkRowMapper, "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(linkAfterUpdate.get(0).getUpdatedAt(),new Timestamp(100000)); + } + + + + + +} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java new file mode 100644 index 0000000..0813c59 --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java @@ -0,0 +1,251 @@ +package scrapper.jdbc; + +import scrapper.environment.IntegrationEnvironment; +import scrapper.environment.TestConfiguration; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.Rollback; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.ScrapperApplication; +import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; +import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; +import ru.tinkoff.edu.java.scrapper.model.Link; +import ru.tinkoff.edu.java.scrapper.model.Relation; +import ru.tinkoff.edu.java.scrapper.model.User; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.SubscriptionJdbcTemplateRepository; + +import java.sql.Timestamp; +import java.util.List; + +@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) +public class JdbcSubscriptionTest extends IntegrationEnvironment { + + @Autowired + private SubscriptionJdbcTemplateRepository subscriptionRepository; + + @Autowired + private LinkRowMapper linkRowMapper; + + @Autowired + private SubscriptionRowMapper subscriptionRowMapper; + + @Autowired + private JdbcTemplate jdbcTemplate; + + + @Test + @Transactional + @Rollback + public void findLinksByChatTest() { + List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 50L, "alucard", "Will", "Smith"); + + //всСго Π΄ΠΎΠ±Π°Π²ΠΈΠΌ 20 ссылок + for (int i = 0; i < 20; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + + //ΠΈΠ· 20-Ρ‚ΠΈ ссылок подпишСмся лишь Π½Π° 10 + for (int i = 0; i < 10; i++) { + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); + } + + //Π½Π° ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ 10 подпишСм Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ + for (int i = 10; i < 20; i++) { + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 50L); + } + + List userLinks = subscriptionRepository.findLinksByChat(42L); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 20); + Assertions.assertEquals(userLinks.size(), 10); + } + + @Test + @Transactional + @Rollback + public void removeRelationTest() { + List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); + + for (int i = 0; i < 20; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + + for (int i = 0; i < 10; i++) { + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); + } + + List userLinksBeforeRemove = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + subscriptionRepository.remove(afterInsertionLink.get(0).getId(), 42L); + subscriptionRepository.remove(afterInsertionLink.get(4).getId(), 42L); + subscriptionRepository.remove(afterInsertionLink.get(6).getId(), 42L); + + List userLinksAfterRemove = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 20); + Assertions.assertEquals(userLinksBeforeRemove.size(), 10); + Assertions.assertEquals(userLinksAfterRemove.size(), 7); + } + + + @Test + @Transactional + @Rollback + public void addRelationTest() { + List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); + + for (int i = 0; i < 20; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + + for (int i = 0; i < 10; i++) { + Relation relation = new Relation(); + relation.setLinkId(afterInsertionLink.get(i).getId()); + relation.setChatId(42L); + subscriptionRepository.addRelation(relation); + } + + + List userLinks = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + Assertions.assertEquals(beforeAddLink.size(), 0); + Assertions.assertEquals(afterInsertionLink.size(), 20); + Assertions.assertEquals(userLinks.size(), 10); + } + + + @Test + @Transactional + @Rollback + public void findChatsByLinkTest() { + List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); + + + for (int i = 0; i < 10; i++) { + User user = new User(42L + i, "robtop21" + i, "Robert", "Polson"); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", + user.getChatId(), + user.getUsername(), + user.getFirstName(), + user.getLastName()); + } + + + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + + + for (int i = 0; i < 7; i++) { + Relation relation = new Relation(); + relation.setLinkId(afterInsertionLink.get(0).getId()); + relation.setChatId(42L + i); + subscriptionRepository.addRelation(relation); + } + + List afterSubscribe = subscriptionRepository.findChatsByLink(afterInsertionLink.get(0).getId()); + + Assertions.assertEquals(beforeAddRelation.size(), 0); + Assertions.assertEquals(afterSubscribe.size(), 7); + } + + @Test + @Transactional + @Rollback + public void findSubscriptionTest() { + List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); + + + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(0).getId(), 42L); + + Relation relation = subscriptionRepository.findSubscription(afterInsertionLink.get(0).getId(), 42L); + + + Assertions.assertEquals(beforeAddRelation.size(),0); + Assertions.assertEquals(afterInsertionLink.size(),1); + Assertions.assertNotNull(relation); + } + + + @Test + @Transactional + @Rollback + public void removeAllByUserTest(){ + List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); + + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 50L, "alucard", "Will", "Smith"); + + //всСго Π΄ΠΎΠ±Π°Π²ΠΈΠΌ 20 ссылок + for (int i = 0; i < 20; i++) { + Link linkToAdd = new Link(); + linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); + linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); + } + + List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); + + //ΠΈΠ· 20-Ρ‚ΠΈ ссылок подпишСмся лишь Π½Π° 10 + for (int i = 0; i < 10; i++) { + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); + } + + //Π½Π° ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ 10 подпишСм Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ + for (int i = 10; i < 20; i++) { + jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 50L); + } + + List userLinksBeforeDelete = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + subscriptionRepository.removeAllByUser(42L); + + List userLinksAfterDelete = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); + + Assertions.assertEquals(beforeAddRelation.size(),0); + Assertions.assertEquals(afterInsertionLink.size(), 20); + Assertions.assertEquals(userLinksBeforeDelete.size(), 10); + Assertions.assertEquals(userLinksAfterDelete.size(), 0); + } + +} diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java new file mode 100644 index 0000000..df7d245 --- /dev/null +++ b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java @@ -0,0 +1,135 @@ +package scrapper.jdbc; + +import scrapper.environment.IntegrationEnvironment; +import scrapper.environment.TestConfiguration; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.Rollback; +import org.springframework.transaction.annotation.Transactional; +import ru.tinkoff.edu.java.scrapper.ScrapperApplication; +import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; +import ru.tinkoff.edu.java.scrapper.model.User; +import ru.tinkoff.edu.java.scrapper.repository.jdbc.UserJdbcTemplateRepository; + +import java.util.List; + +@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) +public class JdbcUserTest extends IntegrationEnvironment { + + @Autowired + private UserJdbcTemplateRepository userRepository; + + @Autowired + private UserRowMapper userRowMapper; + + @Autowired + private JdbcTemplate jdbcTemplate; + + + @Test + @Transactional + @Rollback + public void addUserTest() { + List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + User user = new User(42L, "robtop21", "Robert","Polson"); + + + userRepository.add(user); + + List afterAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + Assertions.assertEquals(beforeAddUser.size(), 0); + Assertions.assertEquals(afterAddUser.size(), 1); + Assertions.assertNotNull(afterAddUser.get(0)); + Assertions.assertEquals(afterAddUser.get(0).getChatId(), 42L); + } + + + @Test + @Transactional + @Rollback + public void removeUserTest() { + List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + User user = new User(42L, "robtop21", "Robert","Polson"); + + + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", + user.getChatId(), + user.getUsername(), + user.getFirstName(), + user.getLastName()); + + + List afterAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + userRepository.remove(42L); + + List afterRemoveUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + + Assertions.assertEquals(beforeAddUser.size(), 0); + Assertions.assertEquals(afterAddUser.size(), 1); + Assertions.assertNotNull(afterAddUser.get(0)); + Assertions.assertEquals(afterAddUser.get(0).getChatId(), 42L); + Assertions.assertEquals(afterRemoveUser.size(), 0); + } + + @Test + @Transactional + @Rollback + public void findAllTest() { + List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + + for (int i = 0; i < 10; i++) { + User user = new User(42L + i, "robtop21" + i, "Robert","Polson"); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", + user.getChatId(), + user.getUsername(), + user.getFirstName(), + user.getLastName()); + } + + List afterInsertionUser = userRepository.findAll(); + + Assertions.assertEquals(beforeAddUser.size(), 0); + Assertions.assertEquals(afterInsertionUser.size(), 10); + } + + + @Test + @Transactional + @Rollback + public void findByChatIdTest(){ + List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + + for (int i = 0; i < 10; i++) { + User user = new User(42L + i, "robtop21" + i, "Robert","Polson"); + + jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", + user.getChatId(), + user.getUsername(), + user.getFirstName(), + user.getLastName()); + } + + List afterInsertionUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); + + User foundedByIdUser = userRepository.findByChatId(42L); + + Assertions.assertEquals(beforeAddUser.size(), 0); + Assertions.assertEquals(afterInsertionUser.size(), 10); + Assertions.assertNotNull(foundedByIdUser); + + } + + +} \ No newline at end of file From 522ae1ead7de26dcbbc23412130726eff8907df2 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Mon, 15 May 2023 14:25:46 +0500 Subject: [PATCH 03/61] Rework --- FP/FP/.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FP/FP/.project b/FP/FP/.project index 89d138f..7b5c63d 100644 --- a/FP/FP/.project +++ b/FP/FP/.project @@ -1,6 +1,6 @@ - project + FP From b85b2010ebabb6fd1edf2b2f208999d4a19cfc61 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:01:18 +0500 Subject: [PATCH 04/61] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=20=D1=81=208=20=D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 9 +- FP/.github/workflows/bot.yml | 75 ------ FP/.github/workflows/scrapper.yml | 74 ------ FP/FP/.project | 18 -- FP/FP/bot/.classpath | 34 --- .../bot/.dbeaver/.credentials-config.json.bak | Bin 112 -> 0 bytes FP/FP/bot/.dbeaver/.data-sources.json.bak | 4 - FP/FP/bot/.dbeaver/.project-metadata.json.bak | 1 - FP/FP/bot/.dbeaver/data-sources.json | 6 - FP/FP/bot/.dbeaver/project-metadata.json | 1 - FP/FP/bot/.dbeaver/project-settings.json | 1 - FP/FP/bot/.gitignore | 1 - FP/FP/bot/.project | 24 -- .../org.eclipse.core.resources.prefs | 6 - .../bot/.settings/org.eclipse.jdt.core.prefs | 9 - .../bot/.settings/org.eclipse.m2e.core.prefs | 4 - FP/FP/bot/pom.xml | 110 -------- .../tinkoff/edu/java/bot/BotApplication.java | 16 -- .../java/bot/advice/AppExceptionHandler.java | 28 -- .../edu/java/bot/client/ScrapperClient.java | 103 ------- .../bot/client/ScrapperClientException.java | 11 - .../edu/java/bot/commands/Command.java | 20 -- .../edu/java/bot/commands/CommandsEnum.java | 33 --- .../edu/java/bot/commands/HelpCommand.java | 23 -- .../edu/java/bot/commands/ListCommand.java | 48 ---- .../edu/java/bot/commands/StartCommand.java | 55 ---- .../edu/java/bot/commands/TrackCommand.java | 47 ---- .../edu/java/bot/commands/UntrackCommand.java | 49 ---- .../bot/configuration/ApplicationConfig.java | 12 - .../bot/configuration/BotConfiguration.java | 78 ------ .../configuration/ClientConfiguration.java | 27 -- .../LinkParserConfiguration.java | 15 -- .../configuration/RabbitMQConfiguration.java | 77 ------ .../edu/java/bot/dto/AddLinkRequest.java | 6 - .../edu/java/bot/dto/ApiErrorResponse.java | 7 - .../tinkoff/edu/java/bot/dto/BotCommand.java | 8 - .../ru/tinkoff/edu/java/bot/dto/Link.java | 10 - .../edu/java/bot/dto/LinkResponse.java | 11 - .../tinkoff/edu/java/bot/dto/LinkUpdate.java | 5 - .../edu/java/bot/dto/ListLinkResponse.java | 6 - .../edu/java/bot/dto/RemoveLinkRequest.java | 5 - .../edu/java/bot/dto/SetCommandRequest.java | 7 - .../tinkoff/edu/java/bot/dto/UserAddDto.java | 8 - .../bot/exceptions/ChatNotFoundException.java | 10 - .../LinkIsNotRegisteredToChatException.java | 10 - .../edu/java/bot/rest/BotRestController.java | 29 -- .../bot/service/ScrapperQueueListener.java | 29 -- .../edu/java/bot/service/UpdateService.java | 8 - .../java/bot/service/UpdateServiceImpl.java | 26 -- .../ru/tinkoff/edu/java/bot/telegram/Bot.java | 52 ---- .../bot/telegram/UserMessageProcessor.java | 126 --------- .../edu/java/bot/telegram/UserState.java | 5 - .../src/main/resources/application.properties | 14 - FP/FP/bot/src/test/java/bot/BotTest.java | 123 --------- FP/FP/docker-compose.yml | 60 ----- FP/FP/link-parser/.classpath | 41 --- FP/FP/link-parser/.gitignore | 1 - FP/FP/link-parser/.project | 23 -- .../org.eclipse.core.resources.prefs | 6 - .../.settings/org.eclipse.jdt.core.prefs | 9 - .../.settings/org.eclipse.m2e.core.prefs | 4 - FP/FP/link-parser/pom.xml | 30 --- .../java/link_parser/link/GitHub_Link.java | 5 - .../java/link_parser/link/Parser_Link.java | 5 - .../link_parser/link/StackOverflow_Link.java | 5 - .../edu/java/link_parser/parser/Abstract.java | 27 -- .../edu/java/link_parser/parser/Github.java | 31 --- .../java/link_parser/parser/Link_Parser.java | 16 -- .../link_parser/parser/StackOverflow.java | 34 --- .../src/test/java/LinkParserTest.java | 99 ------- FP/FP/migrations/01-schema-1.sql | 11 - FP/FP/migrations/02-schema-2.sql | 15 -- FP/FP/migrations/03-schema-3.sql | 10 - FP/FP/migrations/create.sql | 18 -- FP/FP/migrations/delete.sql | 3 - FP/FP/migrations/insert.sql | 37 --- FP/FP/scrapper-jooq/.classpath | 28 -- FP/FP/scrapper-jooq/.gitignore | 1 - FP/FP/scrapper-jooq/.project | 23 -- .../org.eclipse.core.resources.prefs | 4 - .../.settings/org.eclipse.jdt.core.prefs | 9 - .../.settings/org.eclipse.m2e.core.prefs | 4 - FP/FP/scrapper-jooq/pom.xml | 40 --- .../src/main/java/JooqCodegen.java | 54 ---- FP/FP/scrapper/.classpath | 41 --- FP/FP/scrapper/.gitignore | 1 - FP/FP/scrapper/.project | 23 -- .../org.eclipse.core.resources.prefs | 6 - .../.settings/org.eclipse.jdt.core.prefs | 9 - .../.settings/org.eclipse.m2e.core.prefs | 4 - .../java/scrapper/ScrapperApplication.java | 22 -- .../scrapper/advice/AppExceptionHandler.java | 33 --- .../edu/java/scrapper/client/BotClient.java | 38 --- .../java/scrapper/client/GitHubClient.java | 47 ---- .../scrapper/client/StackOverflowClient.java | 44 --- .../configuration/ApplicationConfig.java | 26 -- .../configuration/ClientConfiguration.java | 44 --- .../configuration/HTTPConfiguration.java | 28 -- .../LinkParserConfiguration.java | 14 - .../configuration/RabbitMQConfiguration.java | 50 ---- .../acess/JdbcAccessConfiguration.java | 99 ------- .../acess/JooqAccessConfiguration.java | 84 ------ .../acess/JpaAccessConfiguration.java | 61 ----- .../edu/java/scrapper/dto/AddLinkRequest.java | 5 - .../java/scrapper/dto/ApiErrorResponse.java | 6 - .../edu/java/scrapper/dto/GitHubResponse.java | 25 -- .../edu/java/scrapper/dto/LinkResponse.java | 5 - .../edu/java/scrapper/dto/LinkUpdate.java | 5 - .../java/scrapper/dto/ListLinkResponse.java | 8 - .../java/scrapper/dto/RemoveLinkRequest.java | 5 - .../java/scrapper/dto/StackOverflowItem.java | 8 - .../scrapper/dto/StackOverflowResponse.java | 8 - .../edu/java/scrapper/dto/UserAddDto.java | 8 - .../BadResponseFromApiException.java | 12 - .../exception/BotClientException.java | 11 - .../exception/ChatAlreadyExistException.java | 11 - .../exception/ChatNotFoundException.java | 12 - .../exception/GitHubRequestException.java | 11 - .../LinkIsAlreadyAddedException.java | 12 - .../exception/LinkNotFoundException.java | 12 - .../StackOverflowRequestException.java | 12 - .../java/scrapper/mapper/LinkRowMapper.java | 27 -- .../mapper/SubscriptionRowMapper.java | 20 -- .../java/scrapper/mapper/UserRowMapper.java | 24 -- .../java/scrapper/model/commonDto/Link.java | 31 --- .../java/scrapper/model/commonDto/User.java | 32 --- .../scrapper/model/jdbcAndJooq/Relation.java | 11 - .../java/scrapper/model/jpa/LinkEntity.java | 40 --- .../java/scrapper/model/jpa/UserEntity.java | 30 --- .../jdbc/LinkJdbcTemplateRepository.java | 86 ------ .../SubscriptionJdbcTemplateRepository.java | 75 ------ .../jdbc/UserJdbcTemplateRepository.java | 59 ---- .../jdbcAndJooqContract/LinkRepository.java | 21 -- .../SubscriptionRepository.java | 19 -- .../jdbcAndJooqContract/UserRepository.java | 13 - .../repository/jooq/LinkJooqRepository.java | 98 ------- .../jooq/SubscriptionJooqRepository.java | 80 ------ .../repository/jooq/UserJooqRepository.java | 59 ---- .../repository/jpa/JpaLinkRepository.java | 20 -- .../repository/jpa/JpaUserRepository.java | 22 -- .../scrapper/rest/ChatRestController.java | 30 --- .../scrapper/rest/LinkRestController.java | 44 --- .../schedule/LinkUpdateScheduler.java | 26 -- .../service/ScrapperQueueProducer.java | 26 -- .../service/UpdateNotificationService.java | 8 - .../service/contract/LinkUpdateService.java | 12 - .../service/contract/SubscriptionService.java | 14 - .../service/contract/TgChatService.java | 11 - .../impl/LinkUpdateServiceImpl.java | 156 ----------- .../impl/SubscriptionServiceImpl.java | 99 ------- .../jdbcAndJooq/impl/TgChatServiceImpl.java | 42 --- .../jpa/impl/JpaLinkUpdateServiceImpl.java | 174 ------------ .../jpa/impl/JpaSubscriptionServiceImpl.java | 100 ------- .../jpa/impl/JpaTgChatServiceImpl.java | 43 --- .../src/main/resources/application.properties | 23 -- .../src/main/resources/logback-test.xml | 17 -- .../src/test/java/scrapper/DatabaseTest.java | 38 --- .../java/scrapper/IntegrationEnvironment.java | 54 ---- .../scrapper/environment/DatabaseTest.java | 38 --- .../environment/IntegrationEnvironment.java | 81 ------ .../environment/TestConfiguration.java | 8 - .../test/java/scrapper/jdbc/JdbcLinkTest.java | 151 ----------- .../scrapper/jdbc/JdbcSubscriptionTest.java | 251 ------------------ .../test/java/scrapper/jdbc/JdbcUserTest.java | 135 ---------- FP/bot/pom.xml | 110 ++++++++ .../tinkoff/edu/java/bot/BotApplication.java | 26 ++ .../edu/java/bot/api/BotController.java | 14 + .../exceptionHandler/BotExceptionHandler.java | 36 +++ .../configuration/RabbitMQConfiguration.java | 56 ++++ .../edu/java/bot/configuration/jdbcBean.java | 26 ++ .../records/ApplicationConfig.java | 22 ++ .../java/bot/configuration/records/Bot.java | 4 + .../bot/configuration/records/Scheduler.java | 5 + .../tinkoff/edu/java/bot/handler/BotMain.java | 33 +++ .../ru/tinkoff/edu/java/bot/handler/DB.java | 42 +++ .../edu/java/bot/handler/MessageHandler.java | 39 +++ .../tinkoff/edu/java/bot/handler/Updater.java | 44 +++ .../edu/java/bot/handler/commands/All.java | 7 + .../edu/java/bot/handler/commands/Help.java | 11 + .../edu/java/bot/handler/commands/List.java | 37 +++ .../edu/java/bot/handler/commands/Start.java | 19 ++ .../edu/java/bot/handler/commands/Track.java | 47 ++++ .../java/bot/handler/commands/Untrack.java | 24 ++ .../edu/java/bot/model/ApiErrorResponse.java | 11 + .../edu/java/bot/model/LinkUpdate.java | 6 + .../bot/schedule/LinkUpdaterScheduler.java | 17 ++ .../src/main/resources/application.properties | 9 + FP/docker-compose.yml | 54 ++++ FP/link-parser/pom.xml | 26 ++ .../edu/java/linkparser/LinkParser.java | 18 ++ .../linkparser/absracts/AbstractParser.java | 20 ++ .../java/linkparser/absracts/GitParser.java | 20 ++ .../java/linkparser/absracts/OtherParser.java | 9 + .../java/linkparser/absracts/StackParser.java | 19 ++ .../src/test/java/LinkParserTest.java | 24 ++ FP/migrations/chats_links_scheme.sql | 8 + FP/{FP => }/migrations/master.xml | 4 +- FP/{FP => }/pom.xml | 151 +++++------ FP/{FP => }/scrapper/pom.xml | 86 +++--- .../java/scrapper/ScrapperApplication.java | 29 ++ .../scrapper/api/ScrapperControllerLinks.java | 46 ++++ .../scrapper/api/ScrapperControllerTg.java | 29 ++ .../scrapper/client/ClientConfiguration.java | 57 ++++ .../java/scrapper/client/GitHubRecord.java | 19 ++ .../scrapper/client/StackOverflowRecord.java | 10 + .../java/scrapper/client/WeatherRecord.java | 11 + .../configuration/ApplicationConfig.java | 37 +++ .../configuration/RabbitMQConfiguration.java | 71 +++++ .../exceptions/ScrapperExceptionHandler.java | 78 ++++++ .../EntryExsistException.java | 12 + .../EntryNotExsistException.java | 12 + .../customExceptions/NullDBException.java | 12 + .../customExceptions/NullLinkException.java | 12 + .../UnauthorizationException.java | 12 + .../exceptions/model/ApiErrorResponse.java | 7 + .../java/scrapper/jdbc/JdbcChatService.java | 26 ++ .../java/scrapper/jdbc/JdbcLinkService.java | 81 ++++++ .../java/scrapper/jdbc/config/jdbcBean.java | 25 ++ .../scrapper/jdbc/mappers/ChatMapper.java | 14 + .../scrapper/jdbc/mappers/LinkChatMapper.java | 14 + .../scrapper/jdbc/mappers/LinkMapper.java | 15 ++ .../jdbc/operations/ChatOperations.java | 50 ++++ .../jdbc/operations/LinkChatOperations.java | 61 +++++ .../jdbc/operations/LinkOperations.java | 83 ++++++ .../java/scrapper/model/AddLinkRequest.java | 3 + .../edu/java/scrapper/model/ChatResponse.java | 3 + .../java/scrapper/model/LinkChatResponse.java | 3 + .../edu/java/scrapper/model/LinkResponse.java | 3 + .../edu/java/scrapper/model/LinkUpdate.java | 4 + .../scrapper/model/ListLinksResponse.java | 6 + .../scrapper/model/RemoveLinkRequest.java | 3 + .../java/scrapper/model/UpdateService.java | 4 + .../HandleNoticeServiceImplement.java | 5 + .../rabbitmq/HandleNoticeServiceQueue.java | 16 ++ .../rabbitmq/ScrapperQueueListener.java | 19 ++ .../rabbitmq/ScrapperQueueProducer.java | 28 ++ .../rabbitmq/SendNoticeServiceHttp.java | 11 + .../rabbitmq/SendNoticeServiceImplement.java | 5 + .../rabbitmq/SendNoticeServiceQueue.java | 20 ++ .../schedule/LinkUpdaterScheduler.java | 63 +++++ .../edu/java/scrapper/schedule/Scheduler.java | 3 +- .../src/main/resources/application.properties | 9 + FP/scrapper/src/test/java/BaseTest.java | 11 + .../src/test/java/IntegrationEnvironment.java | 45 ++++ FP/scrapper/src/test/java/JdbcAddTest.java | 9 + README.md | 0 246 files changed, 2058 insertions(+), 5497 deletions(-) delete mode 100644 FP/.github/workflows/bot.yml delete mode 100644 FP/.github/workflows/scrapper.yml delete mode 100644 FP/FP/.project delete mode 100644 FP/FP/bot/.classpath delete mode 100644 FP/FP/bot/.dbeaver/.credentials-config.json.bak delete mode 100644 FP/FP/bot/.dbeaver/.data-sources.json.bak delete mode 100644 FP/FP/bot/.dbeaver/.project-metadata.json.bak delete mode 100644 FP/FP/bot/.dbeaver/data-sources.json delete mode 100644 FP/FP/bot/.dbeaver/project-metadata.json delete mode 100644 FP/FP/bot/.dbeaver/project-settings.json delete mode 100644 FP/FP/bot/.gitignore delete mode 100644 FP/FP/bot/.project delete mode 100644 FP/FP/bot/.settings/org.eclipse.core.resources.prefs delete mode 100644 FP/FP/bot/.settings/org.eclipse.jdt.core.prefs delete mode 100644 FP/FP/bot/.settings/org.eclipse.m2e.core.prefs delete mode 100644 FP/FP/bot/pom.xml delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java delete mode 100644 FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java delete mode 100644 FP/FP/bot/src/main/resources/application.properties delete mode 100644 FP/FP/bot/src/test/java/bot/BotTest.java delete mode 100644 FP/FP/docker-compose.yml delete mode 100644 FP/FP/link-parser/.classpath delete mode 100644 FP/FP/link-parser/.gitignore delete mode 100644 FP/FP/link-parser/.project delete mode 100644 FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs delete mode 100644 FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs delete mode 100644 FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs delete mode 100644 FP/FP/link-parser/pom.xml delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java delete mode 100644 FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java delete mode 100644 FP/FP/link-parser/src/test/java/LinkParserTest.java delete mode 100644 FP/FP/migrations/01-schema-1.sql delete mode 100644 FP/FP/migrations/02-schema-2.sql delete mode 100644 FP/FP/migrations/03-schema-3.sql delete mode 100644 FP/FP/migrations/create.sql delete mode 100644 FP/FP/migrations/delete.sql delete mode 100644 FP/FP/migrations/insert.sql delete mode 100644 FP/FP/scrapper-jooq/.classpath delete mode 100644 FP/FP/scrapper-jooq/.gitignore delete mode 100644 FP/FP/scrapper-jooq/.project delete mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs delete mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs delete mode 100644 FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs delete mode 100644 FP/FP/scrapper-jooq/pom.xml delete mode 100644 FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java delete mode 100644 FP/FP/scrapper/.classpath delete mode 100644 FP/FP/scrapper/.gitignore delete mode 100644 FP/FP/scrapper/.project delete mode 100644 FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs delete mode 100644 FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs delete mode 100644 FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java delete mode 100644 FP/FP/scrapper/src/main/resources/application.properties delete mode 100644 FP/FP/scrapper/src/main/resources/logback-test.xml delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java delete mode 100644 FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java create mode 100644 FP/bot/pom.xml create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/BotController.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/exceptionHandler/BotExceptionHandler.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/jdbcBean.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/ApplicationConfig.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Bot.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Scheduler.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/BotMain.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/MessageHandler.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/Updater.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/All.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Help.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/ApiErrorResponse.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/LinkUpdate.java create mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/schedule/LinkUpdaterScheduler.java create mode 100644 FP/bot/src/main/resources/application.properties create mode 100644 FP/docker-compose.yml create mode 100644 FP/link-parser/pom.xml create mode 100644 FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/LinkParser.java create mode 100644 FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/AbstractParser.java create mode 100644 FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/GitParser.java create mode 100644 FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/OtherParser.java create mode 100644 FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/StackParser.java create mode 100644 FP/link-parser/src/test/java/LinkParserTest.java create mode 100644 FP/migrations/chats_links_scheme.sql rename FP/{FP => }/migrations/master.xml (83%) rename FP/{FP => }/pom.xml (65%) rename FP/{FP => }/scrapper/pom.xml (69%) create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerLinks.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerTg.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/ClientConfiguration.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubRecord.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowRecord.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/WeatherRecord.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/ScrapperExceptionHandler.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryExsistException.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryNotExsistException.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullDBException.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullLinkException.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/UnauthorizationException.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/model/ApiErrorResponse.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcChatService.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcLinkService.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/config/jdbcBean.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/ChatMapper.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkChatMapper.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkMapper.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/ChatOperations.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkChatOperations.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkOperations.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/AddLinkRequest.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ChatResponse.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkChatResponse.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkResponse.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkUpdate.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ListLinksResponse.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/RemoveLinkRequest.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/UpdateService.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceImplement.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceQueue.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueListener.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueProducer.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceHttp.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceImplement.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceQueue.java create mode 100644 FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdaterScheduler.java rename FP/{FP => }/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java (62%) create mode 100644 FP/scrapper/src/main/resources/application.properties create mode 100644 FP/scrapper/src/test/java/BaseTest.java create mode 100644 FP/scrapper/src/test/java/IntegrationEnvironment.java create mode 100644 FP/scrapper/src/test/java/JdbcAddTest.java create mode 100644 README.md diff --git a/.gitignore b/.gitignore index d285d5b..f87b265 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,13 @@ # Compiled class file *.class + # Log file *.log # BlueJ files *.ctxt -# + # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -23,4 +24,8 @@ hs_err_pid* # idea -.idea +FP/.idea/ + +# volumes +FP/migrations/postgres_data/ +FP/rabbitmq/ \ No newline at end of file diff --git a/FP/.github/workflows/bot.yml b/FP/.github/workflows/bot.yml deleted file mode 100644 index a693ee2..0000000 --- a/FP/.github/workflows/bot.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Bot Actions -run-name: Bot Pipeline go! πŸš€ -on: - push: - branches: [ "master", "hw9" ] - paths: - - 'app/bot/**' - pull_request: - branches: [ "master", "hw9" ] - paths: - - 'app/bot/**' - -env: - REGISTRY: ghcr.io - -permissions: - packages: write - - -jobs: - build: - runs-on: ubuntu-latest - steps: - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - - name: Checkout repository - uses: actions/checkout@v3 - - - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." - - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - - name: Set up Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Build with Maven - run: mvn package -pl bot -am - working-directory: app - - - name: Build Docker image - run: docker build -t ${{ env.REGISTRY }}/${{ github.actor }}/bot-image -f app/bot/Dockerfile . - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Docker image to GH Packages - run: docker push ${{ env.REGISTRY }}/${{ github.actor }}/bot-image - - code-check: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Build with Maven and check - run: mvn package -pl bot -am checkstyle:check - working-directory: app diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml deleted file mode 100644 index b202d58..0000000 --- a/FP/.github/workflows/scrapper.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Scrapper Actions -run-name: Scrapper Pipeline go! πŸš€ -on: - push: - branches: [ "master", "hw9" ] - paths: - - 'app/scrapper/**' - pull_request: - branches: [ "master", "hw9" ] - paths: - - 'app/scrapper/**' - -env: - REGISTRY: ghcr.io - -permissions: - packages: write - -jobs: - build: - runs-on: ubuntu-latest - steps: - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - - name: Checkout repository - uses: actions/checkout@v3 - - - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." - - - name: List files in the repository - run: | - ls -la ${{ github.workspace }} - - - name: Set up Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Build with Maven - run: mvn package -pl scrapper -am - working-directory: app - - - name: Build Docker image - run: docker build -t ${{ env.REGISTRY }}/${{ github.actor }}/scrapper-image -f app/scrapper/Dockerfile . - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Docker image to GH Packages - run: docker push ${{ env.REGISTRY }}/${{ github.actor }}/scrapper-image - - code-check: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Build with Maven and check - run: mvn package -pl scrapper -am checkstyle:check - working-directory: app diff --git a/FP/FP/.project b/FP/FP/.project deleted file mode 100644 index 7b5c63d..0000000 --- a/FP/FP/.project +++ /dev/null @@ -1,18 +0,0 @@ - - - FP - - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.jkiss.dbeaver.DBeaverNature - - diff --git a/FP/FP/bot/.classpath b/FP/FP/bot/.classpath deleted file mode 100644 index 0b9fa8d..0000000 --- a/FP/FP/bot/.classpath +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FP/FP/bot/.dbeaver/.credentials-config.json.bak b/FP/FP/bot/.dbeaver/.credentials-config.json.bak deleted file mode 100644 index 8320c631e208c3ad7467cf2d9db83d85e90f14f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112 zcmV-$0FVC>%bw`qlvu4i=Wrho)ja=8tm(6RtT%VUiv(RbXd+9@8O^=>KI816Agz S3>36s#U(-2xgbD9^um4; - - bot - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - org.jkiss.dbeaver.DBeaverNature - - diff --git a/FP/FP/bot/.settings/org.eclipse.core.resources.prefs b/FP/FP/bot/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/FP/FP/bot/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs b/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 5e4ec05..0000000 --- a/FP/FP/bot/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs b/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/FP/FP/bot/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/FP/FP/bot/pom.xml b/FP/FP/bot/pom.xml deleted file mode 100644 index 7d7818b..0000000 --- a/FP/FP/bot/pom.xml +++ /dev/null @@ -1,110 +0,0 @@ - - 4.0.0 - - project - project - 0.0.1-SNAPSHOT - - bot - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework - spring-context-indexer - true - - - org.projectlombok - lombok - true - - - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.0.2 - - - com.github.pengrad - java-telegram-bot-api - 6.6.0 - - - ru.tinkoff.edu - link-parser - 1.0-SNAPSHOT - - - org.springframework - spring-context - 6.0.3 - - - org.springframework - spring-test - 6.0.6 - test - - - org.junit.jupiter - junit-jupiter-params - - - org.mockito - mockito-core - - - org.springframework.boot - spring-boot-starter-amqp - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - org.apache.maven.plugins - maven-checkstyle-plugin - - ../checkstyle.xml - - - - - \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java deleted file mode 100644 index 50cd2b8..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.tinkoff.edu.java.bot; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import ru.tinkoff.edu.java.bot.configuration.ApplicationConfig; - -@SpringBootApplication -@EnableConfigurationProperties(ApplicationConfig.class) -public class BotApplication { - public static void main(String[] args) { - var ctx = SpringApplication.run(BotApplication.class, args); - ApplicationConfig config = ctx.getBean(ApplicationConfig.class); - - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java deleted file mode 100644 index 8ff54fd..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/advice/AppExceptionHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.tinkoff.edu.java.bot.advice; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import ru.tinkoff.edu.java.bot.dto.ApiErrorResponse; -import ru.tinkoff.edu.java.bot.exceptions.ChatNotFoundException; -import ru.tinkoff.edu.java.bot.exceptions.LinkIsNotRegisteredToChatException; - -import java.util.Arrays; - -@RestControllerAdvice -public class AppExceptionHandler { - - @ExceptionHandler({LinkIsNotRegisteredToChatException.class, ChatNotFoundException.class}) - @ResponseStatus(value = HttpStatus.BAD_REQUEST) - public ApiErrorResponse handleNotFoundExceptions(RuntimeException exception) { - return new ApiErrorResponse( - "Error", - HttpStatus.BAD_REQUEST.toString(), - exception.getClass().getName(), - exception.getMessage(), - Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new) - ); - } - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java deleted file mode 100644 index c8b8bab..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClient.java +++ /dev/null @@ -1,103 +0,0 @@ -package ru.tinkoff.edu.java.bot.client; - -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import ru.tinkoff.edu.java.bot.dto.*; - - -public class ScrapperClient { - - private final WebClient webClient; - - private final String wentWrongMessage = "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° нашСй сторонС, ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ ΠΏΠΎΠ·ΠΆΠ΅"; - - //По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - webClient инТСктится ΠΈΠ· ClientConfiguration c baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - public ScrapperClient(WebClient webClient) { - this.webClient = webClient; - } - - //Π—Π΄Π΅ΡΡŒ webClient Π½Π΅ инТСктится, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ baseUrl. - public ScrapperClient(String baseUrl) { - this.webClient = WebClient.create(baseUrl); - } - - public ListLinkResponse getLinks(Long tgChatId) { - ListLinkResponse response = - webClient.get().uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)).exchangeToMono(r -> { - if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { - throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); - } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { - throw new ScrapperClientException( - wentWrongMessage); - } - return r.bodyToMono(ListLinkResponse.class); - }).block(); - - return response; - } - - public LinkResponse addLink(Long tgChatId, AddLinkRequest request) { - LinkResponse response = webClient.post().uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)) - .bodyValue(request).exchangeToMono(r -> { - if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new ScrapperClientException("Бсылка с Ρ‚Π°ΠΊΠΈΠΌ URL ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°"); - } else if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { - throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); - } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { - throw new ScrapperClientException( - wentWrongMessage); - } - return r.bodyToMono(LinkResponse.class); - }).block(); - - return response; - } - - public LinkResponse deleteLink(Long tgChatId, RemoveLinkRequest request) { - LinkResponse response = - webClient.method(HttpMethod.DELETE).uri("/links").header("Tg-Chat-Id", String.valueOf(tgChatId)) - .bodyValue(request).exchangeToMono(r -> { - if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½Π° ссылка"); - } else if (r.statusCode().equals(HttpStatus.NOT_FOUND)) { - throw new ScrapperClientException( - "Бсылка с Ρ‚Π°ΠΊΠΈΠΌ URL Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° ΠΈΠ»ΠΈ Ρ‡Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); - } else if (r.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { - throw new ScrapperClientException( - wentWrongMessage); - } - return r.bodyToMono(LinkResponse.class); - }).block(); - - return response; - } - - public void registerChat(Long tgChatId, UserAddDto userAddDto) { - webClient.post().uri("/tg-chat/{id}", tgChatId).bodyValue(userAddDto).exchangeToMono(response -> { - if (response.statusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½ ID ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ ΡƒΠΆΠ΅ зарСгистрирован"); - } else if (response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { - throw new ScrapperClientException( - wentWrongMessage); - } - return Mono.empty(); - }).block(); - } - - public void deleteChat(Long tgChatId) { - webClient.delete().uri("/tg-chat/{id}", tgChatId).exchangeToMono(response -> { - if (response.statusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new ScrapperClientException("НСкоррСктно ΡƒΠΊΠ°Π·Π°Π½ ID"); - } else if (response.statusCode().equals(HttpStatus.NOT_FOUND)) { - throw new ScrapperClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½"); - } else if (response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { - throw new ScrapperClientException( - wentWrongMessage); - } - return Mono.empty(); - }).block(); - } - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java deleted file mode 100644 index 9ef91d4..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/client/ScrapperClientException.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.bot.client; - -public class ScrapperClientException extends RuntimeException{ - - public ScrapperClientException() { - } - - public ScrapperClientException(String message) { - super(message); - } -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java deleted file mode 100644 index a179c88..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/Command.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import ru.tinkoff.edu.java.bot.dto.BotCommand; - -public interface Command { - String command(); - - String description(); - - String handle(Update update); - - default boolean supports(Update update) { - return update.message().text().equals(command()); - } - - default BotCommand toApiCommand() { - return new BotCommand(command(), description()); - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java deleted file mode 100644 index 1d3852c..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/CommandsEnum.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import java.util.HashMap; -import java.util.Map; - -public enum CommandsEnum { - - START ("/start"), - HELP ("/help"), - LIST ("/list"), - TRACK ("/track"), - UNTRACK ("/untrack"); - - private static final Map BY_LABEL = new HashMap<>(); - - static { - for (CommandsEnum c : values()) { - BY_LABEL.put(c.label, c); - } - } - - private final String label; - - CommandsEnum(String command) { - this.label = command; - } - - public static CommandsEnum valueOfLabel(String label) { - return BY_LABEL.get(label); - } - - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java deleted file mode 100644 index b8e8b62..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/HelpCommand.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.request.SendMessage; -import org.springframework.stereotype.Component; - -@Component -public class HelpCommand implements Command{ - @Override - public String command() { - return "/help"; - } - - @Override - public String description() { - return "вывСсти ΠΎΠΊΠ½ΠΎ с ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ"; - } - - @Override - public String handle(Update update) { - return "Help is executing..."; - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java deleted file mode 100644 index 6a3176e..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/ListCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; -import ru.tinkoff.edu.java.bot.client.ScrapperClientException; -import ru.tinkoff.edu.java.bot.dto.Link; -import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; - -@Component -public class ListCommand implements Command { - - private final ScrapperClient scrapperClient; - - public ListCommand(ScrapperClient scrapperClient) { - this.scrapperClient = scrapperClient; - } - - @Override - public String command() { - return "/list"; - } - - @Override - public String description() { - return "ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ список отслСТиваСмых ссылок"; - } - - @Override - public String handle(Update update) { - long chatId = update.message().chat().id(); - try { - ListLinkResponse response = scrapperClient.getLinks(chatId); - StringBuilder msg = new StringBuilder(); - if (response.size() == 0) - msg.append("Бписок отслСТиваСмых ссылок пуст!"); - else { - msg.append("Бсылок отслСТиваСтся - ").append(response.size()).append("\n\n"); - for (Link link : response.links()) { - msg.append(link.url()).append("\n\n"); - } - } - return msg.toString(); - } catch (ScrapperClientException e){ - return e.getMessage(); - } - } -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java deleted file mode 100644 index 98da89f..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/StartCommand.java +++ /dev/null @@ -1,55 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.model.request.InlineKeyboardButton; -import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup; -import com.pengrad.telegrambot.request.SendMessage; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; -import ru.tinkoff.edu.java.bot.client.ScrapperClientException; -import ru.tinkoff.edu.java.bot.dto.Link; -import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; -import ru.tinkoff.edu.java.bot.dto.UserAddDto; - -@Component -public class StartCommand implements Command { - - private final ScrapperClient scrapperClient; - - public StartCommand(ScrapperClient scrapperClient) { - this.scrapperClient = scrapperClient; - } - - @Value("${tg.bot.token}") - private String token; - - @Override - public String command() { - return "/start"; - } - - @Override - public String description() { - return "Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ"; - } - - @Override - public String handle(Update update) { - long chatId = update.message().chat().id(); - try { - UserAddDto userAddDto = new UserAddDto(update.message().chat().username(), - update.message().chat().firstName(), - update.message().chat().lastName() - ); - scrapperClient.registerChat(chatId, userAddDto); - return "ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Π Π°Π΄ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ, " + update.message().chat().firstName(); - } catch (ScrapperClientException e) { - - return e.getMessage(); - } - - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java deleted file mode 100644 index fed745d..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/TrackCommand.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.request.SendMessage; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; -import ru.tinkoff.edu.java.bot.client.ScrapperClientException; -import ru.tinkoff.edu.java.bot.dto.AddLinkRequest; - -@Component -public class TrackCommand implements Command { - - private final Link_Parser parser; - - public TrackCommand(ScrapperClient scrapperClient, LinkParser parser) { - this.scrapperClient = scrapperClient; - this.parser = parser; - } - - private final ScrapperClient scrapperClient; - - @Override - public String command() { - return "/track"; - } - - @Override - public String description() { - return "Π½Π°Ρ‡Π°Ρ‚ΡŒ отслСТиваниС ссылки"; - } - - @Override - public String handle(Update update) { - long chatId = update.message().chat().id(); - String msg; - try { - if (parser.parseUrl(update.message().text()) != null){ - scrapperClient.addLink(chatId, new AddLinkRequest(update.message().text())); - msg = "Бсылка ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°"; - } else msg = "НСкоррСктная ссылка"; - return msg; - } catch (ScrapperClientException e) { - return e.getMessage(); - } - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java deleted file mode 100644 index df1c58a..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/commands/UntrackCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.tinkoff.edu.java.bot.commands; - -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.request.SendMessage; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; -import ru.tinkoff.edu.java.bot.client.ScrapperClientException; -import ru.tinkoff.edu.java.bot.dto.AddLinkRequest; -import ru.tinkoff.edu.java.bot.dto.RemoveLinkRequest; - -@Component -public class UntrackCommand implements Command{ - - private final ScrapperClient scrapperClient; - - private final Link_Parser parser; - - - public UntrackCommand(ScrapperClient scrapperClient, Link_Parser parser) { - this.scrapperClient = scrapperClient; - this.parser = parser; - } - - @Override - public String command() { - return "/untrack"; - } - - @Override - public String description() { - return "ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ отслСТиваниС ссылки"; - } - - @Override - public String handle(Update update) { - long chatId = update.message().chat().id(); - String msg; - try { - if (parser.parseUrl(update.message().text()) != null){ - scrapperClient.deleteLink(chatId, new RemoveLinkRequest(update.message().text())); - msg = "Бсылка ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΡƒΠ΄Π°Π»Π΅Π½Π°"; - } else msg = "НСкоррСктная ссылка"; - return msg; - } catch (ScrapperClientException e) { - return e.getMessage(); - } - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java deleted file mode 100644 index 02ab1d4..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ApplicationConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.bot.configuration; - -import jakarta.validation.constraints.NotNull; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -@Validated -@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) -public record ApplicationConfig(@NotNull String test, - String queueName, - String exchangeName, - String routingKey) {} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java deleted file mode 100644 index 31177f6..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/BotConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -package ru.tinkoff.edu.java.bot.configuration; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import ru.tinkoff.edu.java.bot.commands.Command; -import ru.tinkoff.edu.java.bot.commands.CommandsEnum; -import ru.tinkoff.edu.java.bot.commands.HelpCommand; -import ru.tinkoff.edu.java.bot.commands.ListCommand; -import ru.tinkoff.edu.java.bot.commands.StartCommand; -import ru.tinkoff.edu.java.bot.commands.TrackCommand; -import ru.tinkoff.edu.java.bot.commands.UntrackCommand; -import ru.tinkoff.edu.java.bot.dto.BotCommand; -import ru.tinkoff.edu.java.bot.dto.SetCommandRequest; -import ru.tinkoff.edu.java.bot.telegram.Bot; - -@Configuration -@Slf4j -public class BotConfiguration { - - @Value("${tg.bot.token}") - private String token; - - @Value("${tg.api.baseUrl}") - private String tgApiBaseUrl; - - private final HelpCommand helpCommand; - private final StartCommand startCommand; - private final ListCommand listCommand; - private final TrackCommand trackCommand; - private final UntrackCommand untrackCommand; - - public BotConfiguration( - HelpCommand helpCommand, - StartCommand startCommand, - ListCommand listCommand, - TrackCommand trackCommand, - UntrackCommand untrackCommand - ) { - this.helpCommand = helpCommand; - this.startCommand = startCommand; - this.listCommand = listCommand; - this.trackCommand = trackCommand; - this.untrackCommand = untrackCommand; - } - - @Bean - public Bot bot() { - EnumMap commands = new EnumMap<>(CommandsEnum.class); - - commands.put(CommandsEnum.HELP, helpCommand); - commands.put(CommandsEnum.LIST, listCommand); - commands.put(CommandsEnum.START, startCommand); - commands.put(CommandsEnum.TRACK, trackCommand); - commands.put(CommandsEnum.UNTRACK, untrackCommand); - - //Π”Π΅Π»Π°Π΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ "МСню" рядом с ΠΈΠΊΠΎΠ½ΠΊΠΎΠΉ скрСпки - //Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ запрос Π½Π° API Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌΠΌΠ° (ΠΌΠ΅Ρ‚ΠΎΠ΄ setMyCommands) со списком ΠΊΠΎΠΌΠ°Π½Π΄ Π² Π²ΠΈΠ΄Π΅ List - List apiCommands = new ArrayList<>(commands.values().stream().map(Command::toApiCommand).toList()); - WebClient botConfClient = WebClient.create(tgApiBaseUrl + token); - botConfClient.post().uri("/setMyCommands").bodyValue(new SetCommandRequest(apiCommands)).exchangeToMono(r -> { - if (!r.statusCode().equals(HttpStatus.OK)) { - log.warn("ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ API Telegram нСдоступСн("); - } - return Mono.empty(); - }).block(); - - return new Bot(token, commands); - } - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java deleted file mode 100644 index f5d3a09..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/ClientConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.tinkoff.edu.java.bot.configuration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.WebClient; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; - - -@Configuration -public class ClientConfiguration { - - @Value("${scrapper.baseurl}") - private String scrapperBaseUrl; - - - @Bean - public WebClient webClient(){ - return WebClient.create(scrapperBaseUrl); - } - - //РСгистрируСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠ°ΠΊ Π±ΠΈΠ½Ρ‹ - @Bean - public ScrapperClient scrapperClient() { - return new ScrapperClient(scrapperBaseUrl); - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java deleted file mode 100644 index eea3511..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/LinkParserConfiguration.java +++ /dev/null @@ -1,15 +0,0 @@ -package ru.tinkoff.edu.java.bot.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; - - -@Configuration -public class LinkParserConfiguration { - - @Bean - public Link_Parser linkParser(){ - return new Link_Parser(); - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java deleted file mode 100644 index fb0772c..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java +++ /dev/null @@ -1,77 +0,0 @@ -package ru.tinkoff.edu.java.bot.configuration; - -import org.springframework.amqp.core.*; -import org.springframework.amqp.support.converter.ClassMapper; -import org.springframework.amqp.support.converter.DefaultClassMapper; -import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; -import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.bot.dto.LinkUpdate; -import ru.tinkoff.edu.java.bot.service.ScrapperQueueListener; -import ru.tinkoff.edu.java.bot.service.UpdateService; - -import java.util.HashMap; -import java.util.Map; - -@Configuration -public class RabbitMQConfiguration { - - private final ApplicationConfig config; - - public RabbitMQConfiguration(ApplicationConfig config) { - this.config = config; - } - - @Bean - Queue queue() { - return QueueBuilder.durable(config.queueName()) - .withArgument("x-dead-letter-exchange", config.exchangeName()) - .withArgument("x-dead-letter-routing-key", config.routingKey() + ".dlq") - .build(); - } - - @Bean - Queue deadLetterQueue() { - return new Queue(config.queueName() + ".dlq", true); - } - - @Bean - DirectExchange exchange() { - return new DirectExchange(config.exchangeName()); - } - - @Bean - Binding binding(Queue queue, DirectExchange exchange) { - return BindingBuilder.bind(queue).to(exchange).with(config.routingKey()); - } - - @Bean - Binding dlqBinding(Queue deadLetterQueue, DirectExchange exchange) { - return BindingBuilder.bind(deadLetterQueue).to(exchange).with(config.routingKey() + ".dlq"); - } - - @Bean - public ClassMapper classMapper() { - Map> mappings = new HashMap<>(); - mappings.put("ru.tinkoff.edu.java.scrapper.dto.LinkUpdate", LinkUpdate.class); - - DefaultClassMapper classMapper = new DefaultClassMapper(); - classMapper.setTrustedPackages("ru.tinkoff.edu.java.scrapper.dto.*"); - classMapper.setIdClassMapping(mappings); - return classMapper; - } - - @Bean - public MessageConverter jsonMessageConverter(ClassMapper classMapper) { - Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter(); - jsonConverter.setClassMapper(classMapper); - return jsonConverter; - } - - @Bean - public ScrapperQueueListener scrapperQueueListener(AmqpTemplate rabbitTemplate, UpdateService updateService) { - return new ScrapperQueueListener(rabbitTemplate, updateService); - } - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java deleted file mode 100644 index 1ff0bee..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/AddLinkRequest.java +++ /dev/null @@ -1,6 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - - -public record AddLinkRequest(String link) { - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java deleted file mode 100644 index d8d6113..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ApiErrorResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -public record ApiErrorResponse(String description, String code, String exceptionName, - String exceptionMessage, String[] stacktrace) { - - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java deleted file mode 100644 index 201c5c6..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/BotCommand.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; - -public record BotCommand(@JsonProperty("command") String command, @JsonProperty("description") String description) implements Serializable { - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java deleted file mode 100644 index 2ab0a84..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/Link.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import java.net.URI; - -public record Link (Long id, URI url){ - @Override - public String toString() { - return "Link{" + "id=" + id + ", url='" + url + '\'' +'}'; - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java deleted file mode 100644 index 396f750..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import java.net.URI; - -public record LinkResponse(long id, URI url) { - - @Override - public String toString() { - return "LinkResponse{" + "id=" + id + ", url=" + url +'}'; - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java deleted file mode 100644 index 8a92e00..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/LinkUpdate.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -public record LinkUpdate(Long id, String url, String description, Long[] tgChatIds) { - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java deleted file mode 100644 index 5d23d7b..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/ListLinkResponse.java +++ /dev/null @@ -1,6 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import java.util.List; - -public record ListLinkResponse(List links, int size) { -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java deleted file mode 100644 index 7e58ba4..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/RemoveLinkRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -public record RemoveLinkRequest(String link) { - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java deleted file mode 100644 index 799cdc3..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/SetCommandRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; - -public record SetCommandRequest(@JsonProperty("commands") List commands) { -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java deleted file mode 100644 index d21ec6a..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/dto/UserAddDto.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.bot.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public record UserAddDto(@JsonProperty("username") String username, - @JsonProperty("first_name") String firstName, - @JsonProperty("last_name") String lastName) { -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java deleted file mode 100644 index 524f6f3..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/ChatNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.tinkoff.edu.java.bot.exceptions; - -public class ChatNotFoundException extends RuntimeException { - public ChatNotFoundException() { - } - - public ChatNotFoundException(String message) { - super(message); - } -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java deleted file mode 100644 index 98c36ae..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/exceptions/LinkIsNotRegisteredToChatException.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.tinkoff.edu.java.bot.exceptions; - -public class LinkIsNotRegisteredToChatException extends RuntimeException { - public LinkIsNotRegisteredToChatException() { - } - - public LinkIsNotRegisteredToChatException(String message) { - super(message); - } -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java deleted file mode 100644 index 2120e54..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/rest/BotRestController.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.tinkoff.edu.java.bot.rest; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import ru.tinkoff.edu.java.bot.dto.LinkUpdate; -import ru.tinkoff.edu.java.bot.service.UpdateService; -import ru.tinkoff.edu.java.bot.service.UpdateServiceImpl; - -@RestController -@Slf4j -public class BotRestController { - - private final UpdateService updateService; - - - public BotRestController(UpdateService updateService) { - this.updateService = updateService; - } - - @PostMapping("updates") - public void sendUpdate(@RequestBody LinkUpdate request) { - log.info("ΠŸΡ€ΠΈΡˆΡ‘Π» запрос Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅: "+request); - updateService.updateLink(request); - } - - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java deleted file mode 100644 index 3cdef00..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/ScrapperQueueListener.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.tinkoff.edu.java.bot.service; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.core.AmqpTemplate; -import org.springframework.amqp.rabbit.annotation.RabbitHandler; -import org.springframework.amqp.rabbit.annotation.RabbitListener; -import ru.tinkoff.edu.java.bot.dto.LinkUpdate; - -@RabbitListener(queues = "${app.queue-name}") -@Slf4j -public class ScrapperQueueListener { - - private final AmqpTemplate rabbitTemplate; - - private final UpdateService updateService; - - public ScrapperQueueListener(AmqpTemplate rabbitTemplate, UpdateService updateService) { - this.rabbitTemplate = rabbitTemplate; - this.updateService = updateService; - } - - @RabbitHandler - public void receiver(LinkUpdate update) { - log.info("Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ: " + update); -// throw new RuntimeException("test exception"); - updateService.updateLink(update); - } - -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java deleted file mode 100644 index ed22af0..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateService.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.bot.service; - -import ru.tinkoff.edu.java.bot.dto.LinkUpdate; - -public interface UpdateService { - -void updateLink(LinkUpdate linkUpdate); -} diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java deleted file mode 100644 index 0e0531d..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/service/UpdateServiceImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.tinkoff.edu.java.bot.service; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import ru.tinkoff.edu.java.bot.dto.LinkUpdate; -import ru.tinkoff.edu.java.bot.telegram.Bot; - -@Service -@Slf4j -public class UpdateServiceImpl implements UpdateService { - - private final Bot bot; - - public UpdateServiceImpl(Bot bot) { - this.bot = bot; - } - - public void updateLink(LinkUpdate linkUpdate) { - log.info("updateLink() method invocation in UpdateServiceImpl"); - String message = "Π’Ρ‹ΡˆΠ»ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎ ссылкС " + linkUpdate.url() + " \n" + linkUpdate.description(); - for (Long chatId : linkUpdate.tgChatIds()) { - bot.sendMessage(chatId, message); - } - } - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java deleted file mode 100644 index 050e804..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/Bot.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.tinkoff.edu.java.bot.telegram; - -import com.pengrad.telegrambot.TelegramBot; -import com.pengrad.telegrambot.UpdatesListener; -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.request.SendMessage; -import jakarta.annotation.PostConstruct; -import lombok.extern.slf4j.Slf4j; -import ru.tinkoff.edu.java.bot.commands.Command; -import ru.tinkoff.edu.java.bot.commands.CommandsEnum; - -import java.util.EnumMap; - -@Slf4j -public class Bot implements AutoCloseable { - - private final TelegramBot bot; - private final UserMessageProcessor userMessageProcessor; - - @PostConstruct - public void init() { - start(); - } - - public Bot(String token, EnumMap commands) { - log.info("Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±ΠΎΡ‚Π°... Π’ΠΎΠΊΠ΅Π½: " + token); - userMessageProcessor = new UserMessageProcessor(commands); - bot = new TelegramBot(token); - } - - public void start() { - log.info("Π‘ΠΎΡ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½..."); - bot.setUpdatesListener(updates -> { - for (Update update : updates) { - if (update.message() != null) { - bot.execute(new SendMessage(update.message().chat().id(), userMessageProcessor.process(update))); - } - - } - return UpdatesListener.CONFIRMED_UPDATES_ALL; - }); - } - - public void sendMessage(Long chatId, String msg) { - bot.execute(new SendMessage(chatId, msg)); - } - - @Override - public void close() throws Exception { - bot.removeGetUpdatesListener(); - } -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java deleted file mode 100644 index ac7b8ac..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserMessageProcessor.java +++ /dev/null @@ -1,126 +0,0 @@ -package ru.tinkoff.edu.java.bot.telegram; - -import com.pengrad.telegrambot.model.Update; -import ru.tinkoff.edu.java.bot.commands.*; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; - -public class UserMessageProcessor { - -// private final List commands; - - // БостояниС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. НуТно для ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ /track ΠΈ /untrack - // TYPING_COMMAND - состояниС Π²Π²ΠΎΠ΄Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ) - // TYPING_TRACKED - состояниС Π²Π²ΠΎΠ΄Π° ссылки для добавлСния - // TYPING_UNTRACKED - состояниС Π²Π²ΠΎΠ΄Π° ссылки для удалСния - private final Map userStateMap; - - private final EnumMap commands; - - public UserMessageProcessor(EnumMap commands) { - this.commands = commands; - userStateMap = new HashMap<>(); - } - - public String process(Update update) { - Command command; - - userStateMap.putIfAbsent(update.message().chat().id(), UserState.TYPING_COMMAND); - switch (userStateMap.get(update.message().chat().id())) { - case TYPING_TRACKED -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - return commands.get(CommandsEnum.valueOfLabel("/track")).handle(update); - } - case TYPING_UNTRACKED -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - return commands.get(CommandsEnum.valueOfLabel("/untrack")).handle(update); - } - case TYPING_COMMAND -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - command = commands.get(CommandsEnum.valueOfLabel(update.message().text())); - if (command == null) { - return "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; - } - if (command instanceof TrackCommand) { - userStateMap.put(update.message().chat().id(), UserState.TYPING_TRACKED); - return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; - } - if (command instanceof UntrackCommand) { - userStateMap.put(update.message().chat().id(), UserState.TYPING_UNTRACKED); - return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; - } - if (command instanceof HelpCommand) { - StringBuilder text = new StringBuilder(); - for (Command c : commands.values()) { - text.append(c.command()).append(" - ").append(c.description()).append("\n"); - } - return text.toString(); - } - return command.handle(update); - } - default -> { - //По Π»ΠΎΠ³ΠΈΠΊΠ΅ этот return Π½ΠΈΠΊΠ°ΠΊ нСдостиТим - return "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° нашСй сторонС"; - - } - } - - } - - }vate final Map userStateMap; - - private final EnumMap commands; - - - public UserMessageProcessor(EnumMap commands) { - this.commands = commands; - userStateMap = new HashMap<>(); - } - - public String process(Update update) { - Command command; - - - userStateMap.putIfAbsent(update.message().chat().id(), UserState.TYPING_COMMAND); - switch (userStateMap.get(update.message().chat().id())) { - case TYPING_TRACKED -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - return commands.get(CommandsEnum.valueOfLabel("/track")).handle(update); - } - case TYPING_UNTRACKED -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - return commands.get(CommandsEnum.valueOfLabel("/untrack")).handle(update); - } - case TYPING_COMMAND -> { - userStateMap.put(update.message().chat().id(), UserState.TYPING_COMMAND); - command = commands.get(CommandsEnum.valueOfLabel(update.message().text())); - if (command == null) - return "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; - if (command instanceof TrackCommand) { - userStateMap.put(update.message().chat().id(), UserState.TYPING_TRACKED); - return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; - } - if (command instanceof UntrackCommand) { - userStateMap.put(update.message().chat().id(), UserState.TYPING_UNTRACKED); - return "ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Ρ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ"; - } - if (command instanceof HelpCommand){ - StringBuilder text = new StringBuilder(); - for (Command c : commands.values()) { - text.append(c.command()).append(" - ").append(c.description()).append("\n"); - } - return text.toString(); - } - return command.handle(update); - } - default -> { - - return "Π§Ρ‚ΠΎ-Ρ‚ΠΎ пошло Π½Π΅ Ρ‚Π°ΠΊ. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π° Π½Π°ΡˆΠ΅Ρ‘ сторонС"; - } - } - - } - - -} \ No newline at end of file diff --git a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java b/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java deleted file mode 100644 index 70bc584..0000000 --- a/FP/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/telegram/UserState.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.bot.telegram; - -public enum UserState { - TYPING_COMMAND, TYPING_TRACKED, TYPING_UNTRACKED -} diff --git a/FP/FP/bot/src/main/resources/application.properties b/FP/FP/bot/src/main/resources/application.properties deleted file mode 100644 index bf1fbc5..0000000 --- a/FP/FP/bot/src/main/resources/application.properties +++ /dev/null @@ -1,14 +0,0 @@ -app.test=beamer-bot -server.port=8080 -springdoc.swagger-ui.path=/swagger-ui -scrapper.baseurl=http://localhost:8080 -tg.bot.token=${TGBOTTOKEN} -tg.api.baseUrl=https://api.telegram.org/bot -spring.rabbitmq.host=localhost -spring.rabbitmq.port=5672 -spring.rabbitmq.username=romanova -spring.rabbitmq.password=2281337 -spring.rabbitmq.listener.simple.default-requeue-rejected=false -app.queue-name=scrapper-bot-queue -app.exchange-name=scrapper-bot-exchange -app.routing-key=scrapper-bot-key \ No newline at end of file diff --git a/FP/FP/bot/src/test/java/bot/BotTest.java b/FP/FP/bot/src/test/java/bot/BotTest.java deleted file mode 100644 index af954d2..0000000 --- a/FP/FP/bot/src/test/java/bot/BotTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package bot; - -import com.pengrad.telegrambot.model.Chat; -import com.pengrad.telegrambot.model.Message; -import com.pengrad.telegrambot.model.Update; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.test.util.ReflectionTestUtils; -import ru.tinkoff.edu.java.bot.client.ScrapperClient; -import ru.tinkoff.edu.java.bot.commands.Command; -import ru.tinkoff.edu.java.bot.commands.CommandsEnum; -import ru.tinkoff.edu.java.bot.commands.ListCommand; -import ru.tinkoff.edu.java.bot.dto.Link; -import ru.tinkoff.edu.java.bot.dto.ListLinkResponse; -import ru.tinkoff.edu.java.bot.telegram.UserMessageProcessor; -import ru.tinkoff.edu.java.bot.telegram.UserState; - -import java.net.URI; -import java.util.*; - -public class BotTest { - - static UserMessageProcessor userMessageProcessor; - - static ScrapperClient scrapperClient; - - static Update updateForListCommand; - static Update updateForInvalidCommand; - static Message messageForListCommand; - static Message messageForInvalidCommand; - - static Chat chat; - - @BeforeAll - static void init() { - //ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π°Π³Π»ΡƒΡˆΠΊΠΈ ΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Ρ‹Π½Π½Ρ‹Π΅, Ρ‚.ΠΊ. Ρƒ Update Π² Π½Π΅Ρ‚ сСттСров, Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ€Π΅Ρ„Π»Π΅ΠΊΡΠΈΡŽ, - //Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ‚ΡƒΠ΄Π° Π½ΡƒΠΆΠ½Ρ‹ΠΉ Message - scrapperClient = Mockito.mock(ScrapperClient.class); - updateForListCommand = new Update(); - messageForListCommand = new Message(); - chat = new Chat(); - ReflectionTestUtils.setField(chat, "id", 42L); - ReflectionTestUtils.setField(messageForListCommand, "chat", chat); - ReflectionTestUtils.setField(messageForListCommand, "text", "/list"); - ReflectionTestUtils.setField(updateForListCommand, "message", messageForListCommand); - - updateForInvalidCommand = new Update(); - messageForInvalidCommand = new Message(); - - ReflectionTestUtils.setField(messageForInvalidCommand, "chat", chat); - ReflectionTestUtils.setField(messageForInvalidCommand, "text", "Azazelo"); - ReflectionTestUtils.setField(updateForInvalidCommand, "message", messageForInvalidCommand); - } - - @Test - @DisplayName("ВСст ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /list, ΠΊΠΎΠ³Π΄Π° список ссылок нСпустой") - public void listCommandTestNotEmpty() { - - //ΠΈΠΌΠΈΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½ΡƒΠΆΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° для Scrapper, Ρ‚.ΠΊ. Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ запроса Π½Π° Scrapper Π²ΠΎ врСмя Π½Π΅ происходит - List listLink = new ArrayList<>(); - listLink.add(new Link(1L, URI.create("https://github.com/lwbeamer/asm-like-language"))); - listLink.add(new Link(2L, URI.create("https://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface"))); - Mockito.when(scrapperClient.getLinks(42L)).thenReturn( - new ListLinkResponse(listLink, listLink.size()) - ); - - EnumMap map = new EnumMap<>(CommandsEnum.class); - map.put(CommandsEnum.LIST, new ListCommand(scrapperClient)); - - userMessageProcessor = new UserMessageProcessor(map); - - String expectedMessage = """ - Бсылок отслСТиваСтся - 2 - - https://github.com/lwbeamer/asm-like-language - - https://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface - - """; - - Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForListCommand)); - } - - - @Test - @DisplayName("ВСст ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /list, ΠΊΠΎΠ³Π΄Π° список ссылок пустой") - public void listCommandTestEmpty() { - Mockito.when(scrapperClient.getLinks(42L)).thenReturn( - new ListLinkResponse(new ArrayList<>(), 0) - ); - - - EnumMap map = new EnumMap<>(CommandsEnum.class); - map.put(CommandsEnum.LIST, new ListCommand(scrapperClient)); - - userMessageProcessor = new UserMessageProcessor(map); - - - String expectedMessage = "Бписок отслСТиваСмых ссылок пуст!"; - - Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForListCommand)); - } - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π²ΠΎΠ΄Π° нСизвСстной ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹") - public void invalidCommandCheck() { - userMessageProcessor = new UserMessageProcessor(new EnumMap<>(CommandsEnum.class)); - - //УстанавливаСм состояниС ΠΏΠ΅Ρ€Π΅Π΄ тСстом - ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π² сосвтоянии "ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ" - Map userStateMap = new HashMap<>(); - userStateMap.put(chat.id(), UserState.TYPING_COMMAND); - ReflectionTestUtils.setField(userMessageProcessor, "userStateMap", userStateMap); - - String expectedMessage = "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. НаТмитС 'МСню' Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список доступных ΠΊΠΎΠΌΠ°Π½Π΄"; - - Assertions.assertEquals(expectedMessage, userMessageProcessor.process(updateForInvalidCommand)); - - } - -} \ No newline at end of file diff --git a/FP/FP/docker-compose.yml b/FP/FP/docker-compose.yml deleted file mode 100644 index c472659..0000000 --- a/FP/FP/docker-compose.yml +++ /dev/null @@ -1,60 +0,0 @@ -services: - postgresql: - image: postgres:15 - container_name: postgresql - ports: - - 5432:5432 - environment: - - POSTGRES_USER=lwbeamer - - POSTGRES_PASSWORD=2281337 - - POSTGRES_DB=scrapper - volumes: - - link-service-data:/var/lib/postgresql/data - networks: - - backend - - liquibase-migrations: - image: liquibase/liquibase:4.18 - depends_on: - - postgresql - command: - - --hub-mode=off - - --changelog-file=master.xml - - --driver=org.postgresql.Driver - - --url=jdbc:postgresql://postgresql:5432/scrapper - - --username=romanova - - --password=12345654321 - - update - volumes: - - ./migrations:/liquibase/changelog - networks: - - backend - -volumes: - link-service-data: - -networks: - backend: - name: backend - rabbit: - image: rabbitmq:3-management - hostname: rabbitmq - container_name: rabbit - ports: - - 15672:15672 - - 5672:5672 - environment: - - RABBITMQ_DEFAULT_USER=romanova - - RABBITMQ_DEFAULT_PASS=12345654321 - volumes: - - rabbitmq-state:/var/lib/rabbitmq - networks: - - backend - -volumes: - link-service-data: - rabbitmq-state: - -networks: - backend: - name: backend \ No newline at end of file diff --git a/FP/FP/link-parser/.classpath b/FP/FP/link-parser/.classpath deleted file mode 100644 index a08fc4f..0000000 --- a/FP/FP/link-parser/.classpath +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FP/FP/link-parser/.gitignore b/FP/FP/link-parser/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/FP/FP/link-parser/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/FP/FP/link-parser/.project b/FP/FP/link-parser/.project deleted file mode 100644 index dec0f32..0000000 --- a/FP/FP/link-parser/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - link-parser - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs b/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/FP/FP/link-parser/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs b/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 5e4ec05..0000000 --- a/FP/FP/link-parser/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs b/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/FP/FP/link-parser/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/FP/FP/link-parser/pom.xml b/FP/FP/link-parser/pom.xml deleted file mode 100644 index 3cfd292..0000000 --- a/FP/FP/link-parser/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - 4.0.0 - - project - project - 0.0.1-SNAPSHOT - - link-parser - - - org.junit.jupiter - junit-jupiter-params - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java deleted file mode 100644 index e244c93..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/GitHub_Link.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.link; - -public record GitHub_Link(String username, String repository) implements Parser_Link { - -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java deleted file mode 100644 index 75db93c..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/Parser_Link.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.link; - -public sealed interface Parser_Link permits GitHub_Link, StackOverflow_Link { - -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java deleted file mode 100644 index 1dad8ad..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/link/StackOverflow_Link.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.link; - -public record StackOverflow_Link(long id) implements Parser_Link { - -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java deleted file mode 100644 index f3641fc..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Abstract.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.parser; - -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; -import java.net.MalformedURLException; -import java.net.URL; - -public abstract class Abstract { - - Abstract nextParser; - - public Abstract(Abstract nextParser) { - this.nextParser = nextParser; - } - - public abstract Parser_Link parser_Link(String url); - - public final URL tweakUrl(String urlString) { - URL url; - try{ - url = new URL(urlString); - } catch (MalformedURLException e){ - System.out.println("Incorrect URL"); - return null; - } - return url; - } -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java deleted file mode 100644 index 13ae325..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Github.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.parser; - -import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; - -import java.net.URL; - - -public class Github extends Abstract { - public Github(Abstract nextParser) { - super(nextParser); - } - - @Override - public Parser_Link parser_Link(String url) { - URL toParse = tweakUrl(url); - if (toParse == null) return null; - - if (toParse.getHost().equals("github.com")) { - String[] tokens = toParse.getFile().substring(1).split("/"); - if (tokens.length >= 2) { - return new GitHub_Link(tokens[0], tokens[1]); - } else return null; - } - - - if (nextParser != null) return nextParser.parser_Link(url); - - return null; - } -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java deleted file mode 100644 index fac1e3f..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/Link_Parser.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.parser; - -import ru.tinkoff.edu.java.link_parser.parser.Abstract; -import ru.tinkoff.edu.java.link_parser.parser.Github; -import ru.tinkoff.edu.java.link_parser.parser.StackOverflow; -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; - -public class Link_Parser { - public Parser_Link parseUrl(String url) { - Abstract parser1 = new Github(null); - Abstract parser2 = new StackOverflow(parser1); - - return parser2.parser_Link(url); - } - -} diff --git a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java b/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java deleted file mode 100644 index e224578..0000000 --- a/FP/FP/link-parser/src/main/java/ru/tinkoff/edu/java/link_parser/parser/StackOverflow.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.tinkoff.edu.java.link_parser.parser; - -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; -import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; -import java.net.URL; -public class StackOverflow extends Abstract { - public StackOverflow(Abstract nextParser) { - super(nextParser); - } - - @Override - public Parser_Link parser_Link(String url) { - - URL toParse = tweakUrl(url); - if (toParse == null) return null; - - - if (toParse.getHost().equals("stackoverflow.com")) { - String[] tokens = toParse.getFile().substring(1).split("/"); - if (tokens.length >= 2 && tokens[0].equals("questions")) { - try { - return new StackOverflow_Link(Long.parseLong(tokens[1])); - } catch (NumberFormatException e) { - System.out.println("Incorrect question ID"); - return null; - } - } else return null; - } - - if (nextParser != null) return nextParser.parser_Link(url); - - return null; - } -} \ No newline at end of file diff --git a/FP/FP/link-parser/src/test/java/LinkParserTest.java b/FP/FP/link-parser/src/test/java/LinkParserTest.java deleted file mode 100644 index bef7512..0000000 --- a/FP/FP/link-parser/src/test/java/LinkParserTest.java +++ /dev/null @@ -1,99 +0,0 @@ -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import ru.tinkoff.edu.java.link_parser.parser.*; -import ru.tinkoff.edu.java.link_parser.link.*; - -public class LinkParserTest { - - static String validGitHubLink; - static String validStackOverflowLink; - static String gitHubNotRepoLink; - static String stackOverflowNotQuestionLink; - static String emptyLink; - static String withoutProtocolLink; - static String unknownHostLink; - static String invalidLink; - - - @BeforeAll - static void init() { - validGitHubLink = "https://github.com/lwbeamer/asm-like-language"; - validStackOverflowLink = "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"; - gitHubNotRepoLink = "https://github.com/issues"; - stackOverflowNotQuestionLink = "https://stackoverflow.co/talent"; - emptyLink = ""; - withoutProtocolLink = "github.com/lwbeamer/asm-like-language"; - unknownHostLink = "https://vk.com/feed"; - invalidLink = "somethingNotValid"; - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки с GitHub") - void checkValidGitHubLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertEquals(new GitHub_Link("lwbeamer", "asm-like-language"), parser.parseUrl(validGitHubLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки со StackOverflow") - void validStackOverflowLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertEquals(new StackOverflow_Link(2336692), parser.parseUrl(validStackOverflowLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки с GitHub, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅ΠΉΡΡ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠ΅ΠΌ") - void gitHubNotRepoLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(gitHubNotRepoLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки со StackOverflow, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰Π΅ΠΉΡΡ вопросом") - void stackOverflowNotQuestionLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(stackOverflowNotQuestionLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ пустой ссылки") - void emptyLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(emptyLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки Π±Π΅Π· указания ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°") - void withoutProtocolLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(withoutProtocolLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ссылки, Π½Π΅ относящСйся ΠΊ отслСТиваСмым рСсурсам") - void unknownHostLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(unknownHostLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ нСпустой Π½Π΅Π²Π°Π»ΠΈΠ΄Π½ΠΎΠΉ ссылки") - void invalidLink() { - Link_Parser parser = new Link_Parser(); - Assertions.assertNull(parser.parseUrl(invalidLink), "ВСст Π½Π΅ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π΅ΡƒΠ·ΡƒΠ»ΡŒΡ‚Π°Ρ‚"); - } - - -} diff --git a/FP/FP/migrations/01-schema-1.sql b/FP/FP/migrations/01-schema-1.sql deleted file mode 100644 index 838947b..0000000 --- a/FP/FP/migrations/01-schema-1.sql +++ /dev/null @@ -1,11 +0,0 @@ ---liquibase formatted sql - ---changeset romanova:create-user-table-1 -CREATE TABLE "user" ( - chat_id bigint PRIMARY KEY, - username text UNIQUE NOT NULL, - first_name text, - last_name text -); - ---rollback DROP TABLE "user"; \ No newline at end of file diff --git a/FP/FP/migrations/02-schema-2.sql b/FP/FP/migrations/02-schema-2.sql deleted file mode 100644 index 0e40afb..0000000 --- a/FP/FP/migrations/02-schema-2.sql +++ /dev/null @@ -1,15 +0,0 @@ ---liquibase formatted sql - ---changeset romanova:create-link-table-1 -CREATE TABLE "link" ( - id bigserial PRIMARY KEY, - url text UNIQUE NOT NULL, - checked_at timestamp NOT NULL, - gh_pushed_at timestamp, - gh_description text, - gh_forks_count int, - so_answer_count int, - so_last_edit_date timestamp -); - ---rollback DROP TABLE "link"; \ No newline at end of file diff --git a/FP/FP/migrations/03-schema-3.sql b/FP/FP/migrations/03-schema-3.sql deleted file mode 100644 index c407b73..0000000 --- a/FP/FP/migrations/03-schema-3.sql +++ /dev/null @@ -1,10 +0,0 @@ ---liquibase formatted sql - ---changeset romanova:create-user-link-table-1 -CREATE TABLE "user_link" ( - link_id bigint REFERENCES "link" (id), - chat_id bigint REFERENCES "user" (chat_id), - PRIMARY KEY (link_id,chat_id) -); - ---rollback DROP TABLE "user_link"; \ No newline at end of file diff --git a/FP/FP/migrations/create.sql b/FP/FP/migrations/create.sql deleted file mode 100644 index a4e2a68..0000000 --- a/FP/FP/migrations/create.sql +++ /dev/null @@ -1,18 +0,0 @@ -create table "user" ( - chat_id bigint primary key, - username text unique not null, - first_name text, - last_name text -); - -create table "link" ( - id bigserial primary key, - url text unique not null, - updated_at timestamp not null -); - -create table "user_link" ( - link_id bigint references "link" (id), - chat_id bigint references "user" (chat_id), - primary key (link_id,chat_id) -) \ No newline at end of file diff --git a/FP/FP/migrations/delete.sql b/FP/FP/migrations/delete.sql deleted file mode 100644 index 1fb56bd..0000000 --- a/FP/FP/migrations/delete.sql +++ /dev/null @@ -1,3 +0,0 @@ -drop table "user_link"; -drop table "user"; -drop table "link"; \ No newline at end of file diff --git a/FP/FP/migrations/insert.sql b/FP/FP/migrations/insert.sql deleted file mode 100644 index 30b59be..0000000 --- a/FP/FP/migrations/insert.sql +++ /dev/null @@ -1,37 +0,0 @@ -insert into "user" (chat_id, username, first_name, last_name) -values (42, 'testUser42', 'test', 'testov'), - (34, 'testUser34', 'test', 'testov'), - (65, 'testUser65', 'test', 'testov'), - (45, 'testUser45', 'test', 'testov'), - (523, 'testUser523', 'test', 'testov'), - (645, 'testUser645', 'test', 'testov'), - (7452, 'testUser7452', 'test', 'testov'), - (44562, 'testUser44562', 'test', 'testov'), - (423452, 'testUser423452', 'test', 'testov'), - (2, 'testUser2', 'test', 'testov'); - -insert into "link" (url, updated_at) -values ('https://stackoverflow.com/questions/14141266/postgresql-foreign-key-on-delete-cascade', '2022-05-19 15:13:27'), - ('https://github.com/linus/doctest','2022-01-31 13:13:50'), - ('https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file','2023-03-27 09:58:45'); - -insert into "user_link" (link_id, chat_id) -values (1,42), - (1,45), - (1,2), - (1,7452), - (2,44562), - (2,423452), - (2,645), - (2,523), - (3,34), - (3,65), - (3,7452), - (3,45), - (4,42), - (4,45), - (4,2), - (4,7452); - - - diff --git a/FP/FP/scrapper-jooq/.classpath b/FP/FP/scrapper-jooq/.classpath deleted file mode 100644 index ead1d0f..0000000 --- a/FP/FP/scrapper-jooq/.classpath +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FP/FP/scrapper-jooq/.gitignore b/FP/FP/scrapper-jooq/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/FP/FP/scrapper-jooq/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/FP/FP/scrapper-jooq/.project b/FP/FP/scrapper-jooq/.project deleted file mode 100644 index f320f87..0000000 --- a/FP/FP/scrapper-jooq/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - scrapper-jooq - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 609d3ca..0000000 --- a/FP/FP/scrapper-jooq/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/resources=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 5e4ec05..0000000 --- a/FP/FP/scrapper-jooq/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs b/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/FP/FP/scrapper-jooq/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/FP/FP/scrapper-jooq/pom.xml b/FP/FP/scrapper-jooq/pom.xml deleted file mode 100644 index b6f0785..0000000 --- a/FP/FP/scrapper-jooq/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - 4.0.0 - - project - project - 0.0.1-SNAPSHOT - - scrapper-jooq - - 17 - 17 - UTF-8 - - - - - org.springframework.boot - spring-boot-starter-jooq - - - org.jooq - jooq-codegen - - - org.jooq - jooq-meta-extensions-liquibase - 3.18.3 - - - org.jooq - jooq-postgres-extensions - 3.18.3 - - - org.liquibase - liquibase-core - - - - \ No newline at end of file diff --git a/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java b/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java deleted file mode 100644 index f8a5bc7..0000000 --- a/FP/FP/scrapper-jooq/src/main/java/JooqCodegen.java +++ /dev/null @@ -1,54 +0,0 @@ -import org.jooq.codegen.GenerationTool; -import org.jooq.meta.jaxb.Configuration; -import org.jooq.meta.jaxb.Database; -import org.jooq.meta.jaxb.Generate; -import org.jooq.meta.jaxb.Generator; -import org.jooq.meta.jaxb.Property; -import org.jooq.meta.jaxb.Target; - -public final class JooqCodegen { - - private JooqCodegen() { - - } - - public static void main(String[] args) throws Exception { - Database database = new Database() - .withName("org.jooq.meta.extensions.liquibase.LiquibaseDatabase") - .withProperties( - new Property().withKey("rootPath").withValue("migrations"), - new Property().withKey("scripts").withValue("master.xml") - ); - - Generate options = new Generate() - .withGeneratedAnnotation(true) - .withGeneratedAnnotationDate(false) - .withNullableAnnotation(true) - .withNullableAnnotationType("org.jetbrains.annotations.Nullable") - .withNonnullAnnotation(true) - .withNonnullAnnotationType("org.jetbrains.annotations.NotNull") - .withJpaAnnotations(false) - .withValidationAnnotations(true) - .withSpringAnnotations(true) - .withConstructorPropertiesAnnotation(true) - .withConstructorPropertiesAnnotationOnPojos(true) - .withConstructorPropertiesAnnotationOnRecords(true) - .withFluentSetters(false) - .withDaos(false) - .withPojos(true); - - Target target = new Target() - .withPackageName("ru.tinkoff.edu.java.scrapper.domain.jooq") - .withDirectory("scrapper/src/main/java"); - - Configuration configuration = new Configuration() - .withGenerator( - new Generator() - .withDatabase(database) - .withGenerate(options) - .withTarget(target) - ); - - GenerationTool.generate(configuration); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/.classpath b/FP/FP/scrapper/.classpath deleted file mode 100644 index a08fc4f..0000000 --- a/FP/FP/scrapper/.classpath +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FP/FP/scrapper/.gitignore b/FP/FP/scrapper/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/FP/FP/scrapper/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/FP/FP/scrapper/.project b/FP/FP/scrapper/.project deleted file mode 100644 index d56fd66..0000000 --- a/FP/FP/scrapper/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - scrapper - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs b/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/FP/FP/scrapper/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs b/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 5e4ec05..0000000 --- a/FP/FP/scrapper/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs b/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/FP/FP/scrapper/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java deleted file mode 100644 index fef7338..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.tinkoff.edu.java.scrapper; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; -import org.springframework.scheduling.annotation.EnableScheduling; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; -import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; -import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaSubscriptionServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaTgChatServiceImpl; - - -@SpringBootApplication -@EnableConfigurationProperties(ApplicationConfig.class) -@EnableScheduling -public class ScrapperApplication { - public static void main(String[] args) { - var ctx = SpringApplication.run(ScrapperApplication.class, args); - ApplicationConfig config = ctx.getBean(ApplicationConfig.class); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java deleted file mode 100644 index 2e1aacf..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/advice/AppExceptionHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.advice; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.client.HttpClientErrorException; -import ru.tinkoff.edu.java.scrapper.dto.ApiErrorResponse; -import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; -import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; -import ru.tinkoff.edu.java.scrapper.exception.LinkIsAlreadyAddedException; -import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; - -import java.util.Arrays; - -@RestControllerAdvice -public class AppExceptionHandler { - - @ExceptionHandler({LinkNotFoundException.class, ChatNotFoundException.class}) - @ResponseStatus(value = HttpStatus.NOT_FOUND) - public ApiErrorResponse handleNotFoundExceptions(RuntimeException exception) { - return new ApiErrorResponse( - "Error", HttpStatus.NOT_FOUND.toString(), exception.getClass().getName(), exception.getMessage(), Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new)); - } - - - @ExceptionHandler({ChatAlreadyExistException.class, LinkIsAlreadyAddedException.class}) - @ResponseStatus(value = HttpStatus.BAD_REQUEST) - public ApiErrorResponse handleBadRequestExceptions(RuntimeException exception) { - return new ApiErrorResponse( - "Error", HttpStatus.BAD_REQUEST.toString(), exception.getClass().getName(), exception.getMessage(), Arrays.stream(exception.getStackTrace()).map(StackTraceElement::toString).toList().toArray(String[]::new)); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java deleted file mode 100644 index 021e3ec..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/BotClient.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.client; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; -import ru.tinkoff.edu.java.scrapper.exception.BotClientException; -import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; - -@Slf4j -public class BotClient { - - @Value("${bot.baseurl}") - private String botBaseUrl; - - private final WebClient webClient; - - public BotClient(WebClient webClient) { - this.webClient = webClient; - } - - public BotClient(String botBaseUrl) { - this.webClient = WebClient.create(botBaseUrl); - } - - public void updateLink(LinkUpdate request) { - log.info("Sending update request to Bot"); - webClient.post().uri("/updates").bodyValue(request).exchangeToMono(r -> { - if (r.statusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new BotClientException("Π§Π°Ρ‚ с Ρ‚Π°ΠΊΠΈΠΌ ID Π½Π΅ зарСгистрирован"); - } - return Mono.empty(); - }).block(); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java deleted file mode 100644 index 156cf35..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubClient.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.client; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.reactive.function.client.WebClient; -import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; -import org.springframework.http.HttpStatus; -import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; - -public class GitHubClient { - - - @Value("${gh.baseurl}") - private String gitHubBaseUrl; - - private final WebClient webClient; - - //для использования baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (бСрётся ΠΈΠ· properties) - public GitHubClient() { - this.webClient = WebClient.create(gitHubBaseUrl); - } - - - //ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ URL - public GitHubClient(String baseUrl) { - this.webClient = WebClient.create(baseUrl); - } - - - public GitHubResponse fetchRepo(String owner, String repo) { - GitHubResponse response = webClient.get().uri("/repos/{owner}/{repo}", owner, repo).exchangeToMono(r->{ - if (!r.statusCode().equals(HttpStatus.OK)) throw new GitHubRequestException("Error with request to GH API"); - return r.bodyToMono(GitHubResponse.class); - }).block(); - - return response; - - } - public void strFetchRepo(String owner, String repo){ - String strReponse = webClient.get().uri("/repos/{owner}/{repo}", owner, repo).exchangeToMono(r->{ - if (!r.statusCode().equals(HttpStatus.OK)) throw new GitHubRequestException("Error with request to GH API"); - return r.bodyToMono(String.class); - }).block(); - - System.out.println(strReponse); - - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java deleted file mode 100644 index 6651dd9..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowClient.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.client; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.http.HttpStatus; -import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; -import ru.tinkoff.edu.java.scrapper.dto.StackOverflowResponse; -import ru.tinkoff.edu.java.scrapper.exception.BadResponseFromApiException; -import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; -import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; -import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; - -public class StackOverflowClient { - - @Value("${so.baseurl}") - private String stackOverflowBaseUrl; - - private final WebClient webClient; - - - //для использования baseUrl ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (бСрётся ΠΈΠ· properties) - public StackOverflowClient() { - this.webClient = WebClient.create(stackOverflowBaseUrl); - } - - - //ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ URL - public StackOverflowClient(String baseUrl) { - this.webClient = WebClient.create(baseUrl); - } - - public StackOverflowItem fetchQuestion(long id) { - - StackOverflowResponse response = webClient.get().uri("/questions/{id}?order=desc&sort=activity&site=stackoverflow", id).exchangeToMono(r->{ - if (!r.statusCode().equals(HttpStatus.OK)) throw new StackOverflowRequestException("Error with request to SO API"); - return r.bodyToMono(StackOverflowResponse.class); - }).block(); - - if (response == null || response.items().size() == 0) - throw new BadResponseFromApiException("API StackOverflow returned bad response"); - - return response.items().get(0); - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java deleted file mode 100644 index 856e54e..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration; - -import jakarta.validation.constraints.NotNull; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.validation.annotation.Validated; -import ru.tinkoff.edu.java.scrapper.schedule.Scheduler; - -@Validated -@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) -public record ApplicationConfig(@NotNull String test, - @NotNull Scheduler scheduler, - @NotNull AccessType dataBaseAccessType, - @NotNull Boolean useQueue, - String queueName, - String exchangeName, - String routingKey){ - - @Bean - public long schedulerIntervalMs(ApplicationConfig config) { - return config.scheduler().interval().toMillis(); - } - public enum AccessType { - JDBC, JPA, JOOQ - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java deleted file mode 100644 index 8694acf..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ClientConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import org.springframework.web.reactive.function.client.WebClient; -import ru.tinkoff.edu.java.scrapper.client.BotClient; - -@Configuration -public class ClientConfiguration { - - @Value("${gh.baseurl}") - private String gitHubBaseUrl; - - @Value("${so.baseurl}") - private String stackOverflowBaseUrl; - - @Value("${bot.baseurl}") - private String botBaseUrl; - - - //РСгистрируСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠ°ΠΊ Π±ΠΈΠ½Ρ‹ - @Bean - public GitHubClient gitHubClientService() { - return new GitHubClient(gitHubBaseUrl); - } - - @Bean - public StackOverflowClient stackOverflowClientService() { - return new StackOverflowClient(stackOverflowBaseUrl); - } - @Bean - public WebClient ghWebClient(){ - return WebClient.create(gitHubBaseUrl); - } - - @Bean - public WebClient soWebClient(){ - return WebClient.create(stackOverflowBaseUrl); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java deleted file mode 100644 index df6780e..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/HTTPConfiguration.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.WebClient; -import ru.tinkoff.edu.java.scrapper.client.BotClient; - -@Configuration -@ConditionalOnProperty(prefix = "app", name = "use-queue", havingValue = "false") -public class HTTPConfiguration { - - @Value("${bot.baseurl}") - private String botBaseUrl; - - - @Bean - public BotClient botClient(){return new BotClient(botBaseUrl);} - - @Bean - public WebClient botWebClient(){ - return WebClient.create(botBaseUrl); - } - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java deleted file mode 100644 index e400f15..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/LinkParserConfiguration.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; - -@Configuration -public class LinkParserConfiguration { - - @Bean - public Link_Parser linkParser(){ - return new Link_Parser(); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java deleted file mode 100644 index d8b1217..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration; - -import org.springframework.amqp.core.*; -import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; -import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.scrapper.service.ScrapperQueueProducer; - -@Configuration -@ConditionalOnProperty(prefix = "app", name = "use-queue", havingValue = "true") -public class RabbitMQConfiguration { - - private final ApplicationConfig config; - - public RabbitMQConfiguration(ApplicationConfig config) { - this.config = config; - } - - @Bean - Queue queue() { - return QueueBuilder.durable(config.queueName()) - .withArgument("x-dead-letter-exchange", config.exchangeName()) - .withArgument("x-dead-letter-routing-key", config.routingKey() + ".dlq") - .build(); - } - - @Bean - DirectExchange exchange() { - return new DirectExchange(config.exchangeName()); - } - - @Bean - Binding binding(Queue queue, DirectExchange exchange) { - return BindingBuilder.bind(queue).to(exchange).with(config.routingKey()); - } - - @Bean - public MessageConverter jsonMessageConverter() { - return new Jackson2JsonMessageConverter(); - } - - - @Bean - public ScrapperQueueProducer scrapperQueueProducer(AmqpTemplate rabbitTemplate) { - return new ScrapperQueueProducer(rabbitTemplate, config); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java deleted file mode 100644 index d70f747..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JdbcAccessConfiguration.java +++ /dev/null @@ -1,99 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration.database.acess; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.core.JdbcTemplate; -import ru.tinkoff.edu.java.link_parser.Link_Parser; -import ru.tinkoff.edu.java.scrapper.client.BotClient; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; -import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; -import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.SubscriptionJdbcTemplateRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.UserJdbcTemplateRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; -import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; -import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.LinkUpdateServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.SubscriptionServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; - -@Configuration -@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jdbc") -public class JdbcAccessConfiguration { - - @Bean - public LinkRowMapper linkRowMapper() { - return new LinkRowMapper(); - } - - @Bean - public SubscriptionRowMapper subscriptionRowMapper() { - return new SubscriptionRowMapper(); - } - - @Bean - public UserRowMapper userRowMapper() { - return new UserRowMapper(); - } - - @Bean - public LinkRepository linkRepository(JdbcTemplate jdbcTemplate, LinkRowMapper linkRowMapper) { - return new LinkJdbcTemplateRepository(jdbcTemplate, linkRowMapper); - } - - @Bean - public SubscriptionRepository subscriptionRepository(JdbcTemplate jdbcTemplate, SubscriptionRowMapper subscriptionRowMapper) { - return new SubscriptionJdbcTemplateRepository(jdbcTemplate, subscriptionRowMapper, linkRowMapper()); - } - - @Bean - public UserRepository userRepository(JdbcTemplate jdbcTemplate, UserRowMapper userRowMapper) { - return new UserJdbcTemplateRepository(jdbcTemplate, userRowMapper); - } - - @Bean - public LinkUpdateService linkUpdateService( - LinkRepository linkRepository, - SubscriptionRepository subscriptionRepository, - Link_Parser linkParser, - GitHubClient gitHubClient, - StackOverflowClient stackOverflowClient, - BotClient botClient - ) { - return new LinkUpdateServiceImpl( - linkRepository, - subscriptionRepository, - linkParser, - gitHubClient, - stackOverflowClient, - botClient); - } - - @Bean - public SubscriptionService subscriptionService( - LinkRepository linkRepository, - SubscriptionRepository subscriptionRepository - ) { - return new SubscriptionServiceImpl( - linkRepository, - subscriptionRepository); - } - - @Bean - public TgChatService tgChatService( - UserRepository userRepository, - SubscriptionRepository subscriptionRepository - ) { - return new TgChatServiceImpl( - userRepository, - subscriptionRepository); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java deleted file mode 100644 index 47864de..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JooqAccessConfiguration.java +++ /dev/null @@ -1,84 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration.database.acess; - -import org.jooq.DSLContext; -import org.jooq.impl.DSL; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.link_parser.Link_Parser; -import ru.tinkoff.edu.java.scrapper.client.BotClient; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; -import ru.tinkoff.edu.java.scrapper.repository.jooq.LinkJooqRepository; -import ru.tinkoff.edu.java.scrapper.repository.jooq.SubscriptionJooqRepository; -import ru.tinkoff.edu.java.scrapper.repository.jooq.UserJooqRepository; -import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; -import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.LinkUpdateServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.SubscriptionServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; -@Configuration -@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jooq") -public class JooqAccessConfiguration { - - - @Bean - public LinkRepository linkRepository(DSLContext dslContext){ - return new LinkJooqRepository(dslContext); - } - - @Bean - public SubscriptionRepository subscriptionRepository(DSLContext dslContext){ - return new SubscriptionJooqRepository(dslContext); - } - - - @Bean - public UserRepository userRepository(DSLContext dslContext){ - return new UserJooqRepository(dslContext); - } - - @Bean - public LinkUpdateService linkUpdateService( - LinkRepository linkRepository, - SubscriptionRepository subscriptionRepository, - LinkParser linkParser, - GitHubClient gitHubClient, - StackOverflowClient stackOverflowClient, - BotClient botClient - ) { - return new LinkUpdateServiceImpl( - linkRepository, - subscriptionRepository, - linkParser, - gitHubClient, - stackOverflowClient, - botClient); - } - - @Bean - public SubscriptionService subscriptionService( - LinkRepository linkRepository, - SubscriptionRepository subscriptionRepository - ) { - return new SubscriptionServiceImpl( - linkRepository, - subscriptionRepository); - } - - @Bean - public TgChatService tgChatService( - UserRepository userRepository, - SubscriptionRepository subscriptionRepository - ) { - return new TgChatServiceImpl( - userRepository, - subscriptionRepository); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java deleted file mode 100644 index ff97aba..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/database/acess/JpaAccessConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.configuration.database.acess; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.tinkoff.edu.java.link_parser.Link_Parser; -import ru.tinkoff.edu.java.scrapper.client.BotClient; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; -import ru.tinkoff.edu.java.scrapper.service.UpdateNotificationService; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; -import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; -import ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl.TgChatServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaLinkUpdateServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaSubscriptionServiceImpl; -import ru.tinkoff.edu.java.scrapper.service.jpa.impl.JpaTgChatServiceImpl; - -@Configuration -@ConditionalOnProperty(prefix = "app", name = "database-access-type", havingValue = "jpa") -public class JpaAccessConfiguration { - - @Bean - public LinkUpdateService linkUpdateService( - JpaLinkRepository linkRepository, - Link_Parser linkParser, - GitHubClient gitHubClient, - StackOverflowClient stackOverflowClient, - BotClient botClient) { - return new JpaLinkUpdateServiceImpl( - linkRepository, - linkParser, - gitHubClient, - stackOverflowClient, - botClient - ); - } - - @Bean - public SubscriptionService subscriptionService( - JpaLinkRepository linkRepository, - JpaUserRepository userRepository) { - return new JpaSubscriptionServiceImpl( - linkRepository, - userRepository - ); - } - - @Bean - public TgChatService tgChatService( - JpaUserRepository userRepository) { - return new JpaTgChatServiceImpl( - userRepository - ); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java deleted file mode 100644 index 97985ba..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/AddLinkRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -public record AddLinkRequest(String link) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java deleted file mode 100644 index 7c065be..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ApiErrorResponse.java +++ /dev/null @@ -1,6 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -public record ApiErrorResponse(String description, String code, String exceptionName, - String exceptionMessage, String[] stacktrace) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java deleted file mode 100644 index 8f6367c..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/GitHubResponse.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.time.OffsetDateTime; - -public record GitHubResponse(@JsonProperty("pushed") OffsetDateTime pushedAt, - @JsonProperty("updated") OffsetDateTime updatedAt, - @JsonProperty("full_name") String fullName, - @JsonProperty("description") String description, - @JsonProperty("forks_count") int forksCount -) { - - -@Override -public String toString() { - return "GitHubResponse{" + - "pushedAt=" + pushedAt + - ", updatedAt=" + updatedAt + - ", fullName='" + fullName + '\'' + - ", description='" + description + '\'' + - ", forksCount=" + forksCount + - '}'; -} - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java deleted file mode 100644 index cadc95f..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkResponse.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -public record LinkResponse(long id, String url) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java deleted file mode 100644 index 1b6410a..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/LinkUpdate.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -public record LinkUpdate(Long id, String url, String description, Long[] tgChatIds) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java deleted file mode 100644 index a142f3a..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/ListLinkResponse.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -import ru.tinkoff.edu.java.scrapper.model.Link; -import java.util.List; - -public record ListLinkResponse(List links, int size) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java deleted file mode 100644 index 09a3867..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/RemoveLinkRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -public record RemoveLinkRequest(String link) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java deleted file mode 100644 index 9e2f0b9..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowItem.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.time.OffsetDateTime; -public record StackOverflowItem(@JsonProperty("last_edit_date") OffsetDateTime lastActivityDate, - @JsonProperty("last_activity_date") OffsetDateTime lastEditDate) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java deleted file mode 100644 index 50227fc..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/StackOverflowResponse.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.time.OffsetDateTime; -import java.util.List; -public record StackOverflowResponse(List items) { - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java deleted file mode 100644 index 58d769c..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/dto/UserAddDto.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public record UserAddDto(@JsonProperty("username") String username, - @JsonProperty("first_name") String firstName, - @JsonProperty("last_name") String lastName) { -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java deleted file mode 100644 index d5be7a4..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BadResponseFromApiException.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class BadResponseFromApiException extends RuntimeException { - - public BadResponseFromApiException() { - } - - public BadResponseFromApiException(String message) { - super(message); - } - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java deleted file mode 100644 index 9ee4d12..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/BotClientException.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class BotClientException extends RuntimeException{ - - public BotClientException() { - } - - public BotClientException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java deleted file mode 100644 index 5dd1124..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatAlreadyExistException.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class ChatAlreadyExistException extends RuntimeException { - - public ChatAlreadyExistException() { - } - - public ChatAlreadyExistException(String message) { - super(message); - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java deleted file mode 100644 index 29dc8cf..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/ChatNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class ChatNotFoundException extends RuntimeException { - - public ChatNotFoundException(String message) { - super(message); - } - - public ChatNotFoundException() { - } - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java deleted file mode 100644 index 9bf30c3..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/GitHubRequestException.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class GitHubRequestException extends RuntimeException{ - - public GitHubRequestException() { - } - - public GitHubRequestException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java deleted file mode 100644 index 58a7dfb..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkIsAlreadyAddedException.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class LinkIsAlreadyAddedException extends RuntimeException { - - - public LinkIsAlreadyAddedException(String message) { - super(message); - } - - public LinkIsAlreadyAddedException() { - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java deleted file mode 100644 index e5c5c62..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/LinkNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class LinkNotFoundException extends RuntimeException { - - public LinkNotFoundException() { - } - - public LinkNotFoundException(String message) { - super(message); - } - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java deleted file mode 100644 index e714110..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exception/StackOverflowRequestException.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.exception; - -public class StackOverflowRequestException extends RuntimeException{ - - public StackOverflowRequestException() { - super(); - } - - public StackOverflowRequestException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java deleted file mode 100644 index 72df1e2..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/LinkRowMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.mapper; - -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.scrapper.model.Link; -import ru.tinkoff.edu.java.scrapper.model.User; - -import java.sql.ResultSet; -import java.sql.SQLException; - -@Component -public class LinkRowMapper implements RowMapper { - - @Override - public Link mapRow(ResultSet rs, int rowNum) throws SQLException { - Link link = new Link(); - link.setId(rs.getLong("id")); - link.setUrl(rs.getString("url")); - link.setCheckedAt(rs.getTimestamp("checked_at")); - link.setGhPushedAt(rs.getTimestamp("gh_pushed_at")); - link.setGhDescription(rs.getString("gh_description")); - link.setGhForksCount(rs.getInt("gh_forks_count")); - link.setSoAnswerCount(rs.getInt("so_answer_count")); - link.setSoLastEditDate(rs.getTimestamp("so_last_edit_date")); - return link; - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java deleted file mode 100644 index bd76b2b..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/SubscriptionRowMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.mapper; - -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.scrapper.model.Relation; -import java.sql.ResultSet; -import java.sql.SQLException; - -@Component -public class SubscriptionRowMapper implements RowMapper { - - @Override - public Relation mapRow(ResultSet rs, int rowNum) throws SQLException { - Relation relation = new Relation(); - relation.setLinkId(rs.getLong("link_id")); - relation.setChatId(rs.getLong("chat_id")); - - return relation; - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java deleted file mode 100644 index 4597040..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/mapper/UserRowMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.mapper; - -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.scrapper.model.User; - -import java.sql.ResultSet; -import java.sql.SQLException; - - -@Component -public class UserRowMapper implements RowMapper { - - - @Override - public User mapRow(ResultSet rs, int rowNum) throws SQLException { - User user = new User(); - user.setChatId(rs.getLong("chat_id")); - user.setUsername(rs.getString("username")); - user.setFirstName(rs.getString("first_name")); - user.setLastName(rs.getString("last_name")); - return user; - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java deleted file mode 100644 index 59b4a92..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/Link.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.model.commonDto; - -import lombok.Data; -import java.sql.Timestamp; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; - -@Data -public class Link { - - - private Long id; - private String url; - private Timestamp checkedAt; - private Timestamp ghPushedAt; - private String ghDescription; - private int ghForksCount; - private Timestamp soLastEditDate; - private int soAnswerCount; - public static Link fromEntity(LinkEntity linkEntity){ - Link link = new Link(); - link.setId(linkEntity.getId()); - link.setUrl(linkEntity.getUrl()); - link.setCheckedAt(linkEntity.getCheckedAt()); - link.setGhDescription(linkEntity.getGhDescription()); - link.setGhPushedAt(linkEntity.getGhPushedAt()); - Integer forks = linkEntity.getGhForksCount(); if (forks == null) link.setGhForksCount(0); else link.setGhForksCount(forks); - Integer answers = linkEntity.getSoAnswerCount(); if (answers == null) link.setSoAnswerCount(0); else link.setSoAnswerCount(answers); - link.setSoLastEditDate(linkEntity.getSoLastEditDate()); - return link; - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java deleted file mode 100644 index 74f7693..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/commonDto/User.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.model.commonDto; - -import lombok.Data; -import lombok.NoArgsConstructor; -import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; - -@Data -@NoArgsConstructor -public class User { - - public User(Long chatId, String username, String firstName, String lastName) { - this.chatId = chatId; - this.username = username; - this.firstName = firstName; - this.lastName = lastName; - } - - private Long chatId; - private String username; - private String firstName; - private String lastName; - public static UserEntity toEntity(User user){ - UserEntity userEntity = new UserEntity(); - - userEntity.setChatId(user.getChatId()); - userEntity.setUsername(user.getUsername()); - userEntity.setFirstName(user.getFirstName()); - userEntity.setLastName(user.getLastName()); - - return userEntity; - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java deleted file mode 100644 index abe684a..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jdbcAndJooq/Relation.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq; - -import lombok.Data; - -@Data -public class Relation { - - private Long linkId; - private Long chatId; - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java deleted file mode 100644 index bd4469b..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/LinkEntity.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.model.jpa; - -import jakarta.persistence.*; -import lombok.Data; -import java.sql.Timestamp; -import java.util.List; - -@Entity -@Table(name = "link") -@Data -public class LinkEntity { - - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "url", unique = true, nullable = false) - private String url; - - @Column(name = "checked_at", nullable = false) - private Timestamp checkedAt; - - @Column(name = "gh_pushed_at") - private Timestamp ghPushedAt; - - @Column(name = "gh_description") - private String ghDescription; - - @Column(name = "gh_forks_count") - private Integer ghForksCount; - - @Column(name = "so_last_edit_date") - private Timestamp soLastEditDate; - - @Column(name = "so_answer_count") - private Integer soAnswerCount; - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java deleted file mode 100644 index 8f49d40..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/jpa/UserEntity.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.model.jpa; - -import jakarta.persistence.*; -import lombok.Data; -import java.util.List; - -@Entity -@Table(name = "\"user\"") -@Data -public class UserEntity { - - @Id - @Column(name = "chat_id") - private Long chatId; - - @Column(name = "username", unique = true, nullable = false) - private String username; - - @Column(name = "first_name") - private String firstName; - - @Column(name = "last_name") - private String lastName; - - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "user_link", - joinColumns = @JoinColumn(name = "chat_id"), - inverseJoinColumns = @JoinColumn(name = "link_id")) - private List links; -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java deleted file mode 100644 index 38d0931..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/LinkJdbcTemplateRepository.java +++ /dev/null @@ -1,86 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbc; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.repository.LinkRepository; - -import java.sql.Timestamp; -import java.util.List; - -@Slf4j -public class LinkJdbcTemplateRepository implements LinkRepository { - - - private final JdbcTemplate jdbcTemplate; - - private final LinkRowMapper linkRowMapper; - - public LinkJdbcTemplateRepository(JdbcTemplate jdbcTemplate, LinkRowMapper linkRowMapper) { - this.jdbcTemplate = jdbcTemplate; - this.linkRowMapper = linkRowMapper; - } - - - @Override - public List findAll() { - log.info("findAll() method invocation in linkRepo"); - String sql = "select * from link"; - return jdbcTemplate.query(sql, linkRowMapper); - } - - @Override - public Link findByUrl(String url) { - log.info("findByUrl() method invocation in linkRepo"); - String sql = "select * from link where link.url = ?"; - List link = jdbcTemplate.query(sql, linkRowMapper, url); - return link.size() == 0 ? null : link.get(0); - } - - @Override - public void add(Link link) { - log.info("add() method invocation in linkRepo"); - String sql = "insert into link (url, updated_at) values(?, ?)"; - jdbcTemplate.update(sql, link.getUrl(), link.getUpdatedAt()); - } - - - @Override - public void updateDate(Link link) { - log.info("updateDate() method invocation in linkRepo"); - String sql = "update link set updated_at = ? where id = ?"; - jdbcTemplate.update(sql, link.getUpdatedAt(), link.getId()); - } - - @Override - public void remove(Long id) { - log.info("remove() method invocation in linkRepo"); - String sql = "delete from link where link.id = ?"; - jdbcTemplate.update(sql, id); - } - - @Override - //поиск ссылок ΠΏΠΎ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ - public List findOldLinks(Long timeUpdateDelta) { - log.info("findOldLinks() method invocation in linkRepo"); - Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDelta*1000); - String sql = "select * from link where link.updated_at < ? order by link.updated_at desc"; - return jdbcTemplate.query(sql,linkRowMapper,compareDate); - } - @Override - public void updateGhLink(Link link) { - log.info("updateGhLink() method invocation in linkJdbcRepo"); - String sql = "update link set gh_forks_count = ?, gh_description = ?, gh_pushed_at = ? where id = ?"; - jdbcTemplate.update(sql, link.getGhForksCount(), link.getGhDescription(), link.getGhPushedAt(), link.getId()); - } - - @Override - public void updateSoLink(Link link) { - log.info("updateSoLastEditDate() method invocation in linkJdbcRepo"); - String sql = "update link set so_last_edit_date = ?, so_answer_count = ? where id = ?"; - jdbcTemplate.update(sql, link.getSoLastEditDate(), link.getSoAnswerCount(), link.getId()); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java deleted file mode 100644 index fce7af7..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/SubscriptionJdbcTemplateRepository.java +++ /dev/null @@ -1,75 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbc; - - -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; -import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; -import ru.tinkoff.edu.java.scrapper.model.Link; -import ru.tinkoff.edu.java.scrapper.model.Relation; -import ru.tinkoff.edu.java.scrapper.model.User; -import ru.tinkoff.edu.java.scrapper.repository.SubscriptionRepository; - -import java.util.List; - -@Repository -@Slf4j -public class SubscriptionJdbcTemplateRepository implements SubscriptionRepository { - - private final JdbcTemplate jdbcTemplate; - - private final SubscriptionRowMapper subscriptionRowMapper; - - private final LinkRowMapper linkRowMapper; - - public SubscriptionJdbcTemplateRepository(JdbcTemplate jdbcTemplate, SubscriptionRowMapper subscriptionRowMapper, LinkRowMapper linkRowMapper) { - this.jdbcTemplate = jdbcTemplate; - this.subscriptionRowMapper = subscriptionRowMapper; - this.linkRowMapper = linkRowMapper; - } - - @Override - public List findLinksByChat(Long chatId) { - log.info("findLinksByChat() method invocation in subscriptionRepo"); - String sql = "select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?"; - return jdbcTemplate.query(sql, linkRowMapper, chatId); - } - - @Override - public List findChatsByLink(Long linkId) { - log.info("findChatsByLink() method invocation in subscriptionRepo"); - String sql = "select * from user_link where user_link.link_id = ?"; - return jdbcTemplate.query(sql, subscriptionRowMapper, linkId); - } - - @Override - public Relation findSubscription(Long linkId, Long chatId) { - log.info("findSubscription() method invocation in subscriptionRepo"); - String sql = "select * from user_link rel where rel.chat_id = ? and rel.link_id = ?"; - List relation = jdbcTemplate.query(sql, subscriptionRowMapper, chatId, linkId); - return relation.size() == 0 ? null : relation.get(0); - } - - - @Override - public void addRelation(Relation relation) { - log.info("addRelation() method invocation in subscriptionRepo"); - String sql = "insert into user_link (link_id, chat_id) values(?, ?)"; - jdbcTemplate.update(sql, relation.getLinkId(), relation.getChatId()); - } - - @Override - public void remove(Long linkId, Long chatId) { - log.info("remove() method invocation in subscriptionRepo"); - String sql = "delete from user_link where user_link.link_id = ? and user_link.chat_id = ?"; - jdbcTemplate.update(sql, linkId, chatId); - } - - @Override - public void removeAllByUser(Long chatId) { - log.info("removeAllByUser() method invocation in subscriptionRepo"); - String sql = "delete from user_link where user_link.chat_id = ?"; - jdbcTemplate.update(sql, chatId); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java deleted file mode 100644 index d59d09c..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbc/UserJdbcTemplateRepository.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbc; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; -import ru.tinkoff.edu.java.scrapper.model.User; -import ru.tinkoff.edu.java.scrapper.repository.UserRepository; - -import java.util.List; - -@Repository -@Slf4j -public class UserJdbcTemplateRepository implements UserRepository { - - - private final JdbcTemplate jdbcTemplate; - - private final UserRowMapper userRowMapper; - - - public UserJdbcTemplateRepository(JdbcTemplate jdbcTemplate, UserRowMapper userRowMapper) { - this.jdbcTemplate = jdbcTemplate; - this.userRowMapper = userRowMapper; - } - - @Override - public List findAll(){ - log.info("findAll() method invocation in userRepo"); - String sql = "select * from \"user\""; - return jdbcTemplate.query(sql, userRowMapper); - } - - @Override - public User findByChatId(Long id) { - log.info("findByChatId() method invocation in userRepo"); - String sql = "select * from \"user\" where \"user\".chat_id = ?"; - List user = jdbcTemplate.query(sql, userRowMapper, id); - return user.size() == 0 ? null : user.get(0); - } - - @Override - public void add(User user){ - log.info("add() method invocation in userRepo"); - String sql = "insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)"; - jdbcTemplate.update(sql, user.getChatId(), user.getUsername(), user.getFirstName(), user.getLastName()); - } - - @Override - public void remove(Long chatId){ - log.info("remove() method invocation in userRepo"); - String sql = "delete from \"user\" where \"user\".chat_id = ?"; - jdbcTemplate.update(sql,chatId); - } - - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java deleted file mode 100644 index 0298278..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/LinkRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import java.util.List; - - -public interface LinkRepository { - List findAll(); - - - Link findByUrl(String url); - void add(Link link); - - void updateCheckDate(Link link); - void remove(Long id); - List findOldLinks(Long timeUpdateDeltaInSeconds); - - void updateGhLink(Link link); - - void updateSoLink(Link link); -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java deleted file mode 100644 index 0dde7e4..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/SubscriptionRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; - -import java.util.List; - -public interface SubscriptionRepository { - - List findLinksByChat(Long chatId); - - List findChatsByLink(Long linkId); - - Relation findSubscription(Long linkId, Long chatId); - void addRelation(Relation relation); - void remove(Long linkId, Long chatId); - - void removeAllByUser(Long chatId); -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java deleted file mode 100644 index 87cbf34..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jdbcAndJooqContract/UserRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; -import java.util.List; - -public interface UserRepository { - List findAll(); - - User findByChatId(Long id); - void add(User user); - void remove(Long id); - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java deleted file mode 100644 index 7371ffd..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/LinkJooqRepository.java +++ /dev/null @@ -1,98 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jooq; - -import lombok.extern.slf4j.Slf4j; -import org.jooq.DSLContext; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; -import java.sql.Timestamp; -import java.util.List; -import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.Link.*; - -@Slf4j -public class LinkJooqRepository implements LinkRepository { - - - private final DSLContext dslContext; - - - - public LinkJooqRepository(DSLContext dslContext) { - this.dslContext = dslContext; - } - - @Override - public List findAll() { - log.info("findAll() method invocation in linkJooqRepo"); - return dslContext.selectFrom(LINK) - .fetchInto(Link.class); - } - - @Override - public Link findByUrl(String url) { - log.info("findByUrl() method invocation in linkJooqRepo"); - return dslContext.selectFrom(LINK) - .where(LINK.URL.eq(url)) - .fetchOneInto(Link.class); - } - - @Override - public void add(Link link) { - log.info("add() method invocation in linkJooqRepo"); - dslContext.insertInto(LINK) - .set(LINK.URL, link.getUrl()) - .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) - .execute(); - } - - @Override - public void updateCheckDate(Link link) { - log.info("updateDate() method invocation in linkJooqRepo"); - dslContext.update(LINK) - .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) - .where(LINK.ID.eq(link.getId())) - .execute(); - } - - @Override - public void remove(Long id) { - log.info("remove() method invocation in linkJooqRepo"); - dslContext.deleteFrom(LINK) - .where(LINK.ID.eq(id)) - .execute(); - } - - @Override - public List findOldLinks(Long timeUpdateDeltaInSeconds) { - log.info("findOldLinks() method invocation in linkJooqRepo"); - Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds * 1000); - return dslContext.selectFrom(LINK) - .where(LINK.CHECKED_AT.lessThan(compareDate.toLocalDateTime())) - .orderBy(LINK.CHECKED_AT.desc()) - .fetchInto(Link.class); - } - - @Override - public void updateGhLink(Link link) { - log.info("updateGhLink() method invocation in linkJooqRepo"); - dslContext.update(LINK) - .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) - .set(LINK.GH_FORKS_COUNT, link.getGhForksCount()) - .set(LINK.GH_DESCRIPTION, link.getGhDescription()) - .set(LINK.GH_PUSHED_AT, link.getGhPushedAt().toLocalDateTime()) - .where(LINK.ID.eq(link.getId())) - .execute(); - } - - @Override - public void updateSoLink(Link link) { - log.info("updateSoLink() method invocation in linkJooqRepo"); - dslContext.update(LINK) - .set(LINK.CHECKED_AT, link.getCheckedAt().toLocalDateTime()) - .set(LINK.SO_LAST_EDIT_DATE, link.getSoLastEditDate().toLocalDateTime()) - .set(LINK.SO_ANSWER_COUNT, link.getSoAnswerCount()) - .where(LINK.ID.eq(link.getId())) - .execute(); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java deleted file mode 100644 index 6463de4..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/SubscriptionJooqRepository.java +++ /dev/null @@ -1,80 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jooq; - -import lombok.extern.slf4j.Slf4j; -import org.jooq.DSLContext; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.model.Link; -import ru.tinkoff.edu.java.scrapper.model.Relation; -import ru.tinkoff.edu.java.scrapper.repository.SubscriptionRepository; - -import java.util.List; - -import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.UserLink.*; -import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.Link.*; - - -@Repository -@Slf4j -public class SubscriptionJooqRepository implements SubscriptionRepository { - - - private final DSLContext dslContext; - - - public SubscriptionJooqRepository(DSLContext dslContext) { - this.dslContext = dslContext; - } - - - @Override - public List findLinksByChat(Long chatId) { - log.info("findLinksByChat() method invocation in subscriptionJooqRepo"); - return dslContext.select() - .from(LINK) - .join(USER_LINK).on(LINK.ID.eq(USER_LINK.LINK_ID)) - .where(USER_LINK.CHAT_ID.eq(chatId)) - .fetchInto(Link.class); - } - - @Override - public List findChatsByLink(Long linkId) { - log.info("findChatsByLink() method invocation in subscriptionJooqRepo"); - return dslContext.select() - .from(USER_LINK) - .where(USER_LINK.LINK_ID.eq(linkId)) - .fetchInto(Relation.class); - } - - @Override - public Relation findSubscription(Long linkId, Long chatId) { - log.info("findSubscription() method invocation in subscriptionJooqRepo"); - return dslContext.select() - .from(USER_LINK) - .where(USER_LINK.CHAT_ID.eq(chatId).and(USER_LINK.LINK_ID.eq(linkId))) - .fetchOneInto(Relation.class); - } - - @Override - public void addRelation(Relation relation) { - log.info("addRelation() method invocation in subscriptionJooqRepo"); - dslContext.insertInto(USER_LINK, USER_LINK.LINK_ID, USER_LINK.CHAT_ID) - .values(relation.getLinkId(), relation.getChatId()) - .execute(); - } - - @Override - public void remove(Long linkId, Long chatId) { - log.info("remove() method invocation in subscriptionJooqRepo"); - dslContext.deleteFrom(USER_LINK) - .where(USER_LINK.LINK_ID.eq(linkId).and(USER_LINK.CHAT_ID.eq(chatId))) - .execute(); - } - - @Override - public void removeAllByUser(Long chatId) { - log.info("removeAllByUser() method invocation in subscriptionJooqRepo"); - dslContext.deleteFrom(USER_LINK) - .where(USER_LINK.CHAT_ID.eq(chatId)) - .execute(); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java deleted file mode 100644 index d942314..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jooq/UserJooqRepository.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jooq; - -import lombok.extern.slf4j.Slf4j; -import org.jooq.DSLContext; -import org.springframework.stereotype.Repository; -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; -import java.util.List; - -import static ru.tinkoff.edu.java.scrapper.domain.jooq.tables.User.*; - -@Repository -@Slf4j -public class UserJooqRepository implements UserRepository { - - private final DSLContext dslContext; - - - public UserJooqRepository(DSLContext dslContext) { - this.dslContext = dslContext; - } - - @Override - public List findAll() { - log.info("findAll() method invocation in userJooqRepo"); - - return dslContext.selectFrom(USER).fetchInto(User.class); - } - - @Override - public User findByChatId(Long id) { - log.info("findByChatId() method invocation in userJooqRepo"); - - return dslContext.selectFrom(USER) - .where(USER.CHAT_ID.eq(id)) - .fetchOneInto(User.class); - } - - @Override - public void add(User user) { - log.info("add() method invocation in userJooqRepo"); - - dslContext.insertInto(USER) - .set(USER.CHAT_ID, user.getChatId()) - .set(USER.USERNAME, user.getUsername()) - .set(USER.FIRST_NAME, user.getFirstName()) - .set(USER.LAST_NAME, user.getLastName()) - .execute(); - } - - @Override - public void remove(Long chatId) { - log.info("remove() method invocation in userJooqRepo"); - - dslContext.deleteFrom(USER) - .where(USER.CHAT_ID.eq(chatId)) - .execute(); - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java deleted file mode 100644 index 2f1dab8..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaLinkRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jpa; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; - -import java.sql.Timestamp; -import java.util.List; -import java.util.Optional; - -public interface JpaLinkRepository extends JpaRepository { - Optional findByUrl(String url); - - @Query("select u.chatId from UserEntity u join u.links l where l.id = :id") - List findChatIdsByLinkId(@Param("id") Long id); - - List findByCheckedAtLessThanOrderByCheckedAtDesc(Timestamp compareDate); - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java deleted file mode 100644 index cdcb762..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/repository/jpa/JpaUserRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.repository.jpa; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; -import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; - -import java.util.List; -import java.util.Optional; - -public interface JpaUserRepository extends JpaRepository { - - @Query("select link from UserEntity u join u.links link where u.chatId = :chatId") - List findAllLinksByChat(@Param("chatId") Long chatId); - - - @Query("select u from UserEntity u join fetch u.links link where u.chatId = :chatId") - Optional findByChatIdWithLinks(@Param("chatId") Long chatId); - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java deleted file mode 100644 index 388ebac..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/ChatRestController.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.rest; - -import org.springframework.web.bind.annotation.*; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; -import ru.tinkoff.edu.java.scrapper.dto.UserAddDto; -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; - -@RestController -@RequestMapping("/tg-chat") -public class ChatRestController { - - - private final TgChatService chatService; - - public ChatRestController(TgChatService chatService) { - this.chatService = chatService; - } - - @PostMapping(value = "{id}") - public void registerChat(@PathVariable Long id, @RequestBody UserAddDto userAddDto) { - chatService.register(new User(id, userAddDto.username(), userAddDto.firstName(), userAddDto.lastName())); - } - - @DeleteMapping(value = "{id}") - public void deleteChat(@PathVariable Long id) { - chatService.unregister(id); - } - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java deleted file mode 100644 index 5aef3ac..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rest/LinkRestController.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.rest; - -import org.springframework.web.bind.annotation.*; -import ru.tinkoff.edu.java.scrapper.dto.AddLinkRequest; -import ru.tinkoff.edu.java.scrapper.dto.LinkResponse; -import ru.tinkoff.edu.java.scrapper.dto.ListLinkResponse; -import ru.tinkoff.edu.java.scrapper.dto.RemoveLinkRequest; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkService; -import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; -import java.net.URI; -import java.util.List; - -@RestController -@RequestMapping("/links") -public class LinkRestController { - - private final SubscriptionService subscriptionService; - - public LinkRestController(SubscriptionService subscriptionService) { - this.subscriptionService = subscriptionService; - } - - @GetMapping - public ListLinkResponse getLinks(@RequestHeader("Tg-Chat-Id") Long chatId) { - List list = subscriptionService.getLinksByChat(chatId); - return new ListLinkResponse(list, list.size()); - } - - @PostMapping - public LinkResponse addLink(@RequestHeader("Tg-Chat-Id") Long chatId, @RequestBody AddLinkRequest request) { - Link link = subscriptionService.subscribe(chatId, URI.create(request.link())); - return new LinkResponse(link.getId(), link.getUrl()); - } - - @DeleteMapping - public LinkResponse deleteLink(@RequestHeader("Tg-Chat-Id") Long chatId, @RequestBody RemoveLinkRequest request) { - Link link = subscriptionService.unsubscribe(chatId, URI.create(request.link())); - if (link == null) throw new LinkNotFoundException("Бсылка с Ρ‚Π°ΠΊΠΈΠΌ url Π½Π΅ отслСТиваСтся!"); - return new LinkResponse(link.getId(), link.getUrl()); - } - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java deleted file mode 100644 index eec99f7..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdateScheduler.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.schedule; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; - -import java.util.List; - -@Slf4j -@Component -public class LinkUpdateScheduler { - - private final LinkUpdateService linkUpdateService; - - - public LinkUpdateScheduler(LinkUpdateService linkUpdateService, Parser_Link linkParser) { - this.linkUpdateService = linkUpdateService; - } - - @Scheduled(fixedDelayString = "#{@schedulerIntervalMs}") - public void update() { - log.info("update() method invocation in LinkUpdateScheduler"); - linkUpdateService.updateLinks(); - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java deleted file mode 100644 index 91471de..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/ScrapperQueueProducer.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.core.AmqpTemplate; -import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; -import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; - -@Slf4j -//Π±ΠΈΠ½ рСгистрируСтся Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅, Ρ‚.ΠΊ. Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² случаС общСния ΠΏΠΎ HTTP -public class ScrapperQueueProducer implements UpdateNotificationService { - - private final AmqpTemplate rabbitTemplate; - - private final ApplicationConfig config; - - - public ScrapperQueueProducer(AmqpTemplate rabbitTemplate, ApplicationConfig config) { - this.rabbitTemplate = rabbitTemplate; - this.config = config; - } - - public void updateLink(LinkUpdate update) { - rabbitTemplate.convertAndSend(config.exchangeName(), config.routingKey(), update); - log.info("UpdateMessage " + update + " has been sent"); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java deleted file mode 100644 index 61ee96d..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/UpdateNotificationService.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service; - -import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; - -public interface UpdateNotificationService { - - void updateLink(LinkUpdate request); -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java deleted file mode 100644 index 10646d7..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/LinkUpdateService.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.contract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import java.util.List; - -public interface LinkUpdateService { - - - List getOldLinks(); - - void updateLinks(); -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java deleted file mode 100644 index b35caad..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/SubscriptionService.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.contract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import java.net.URI; -import java.util.List; - -public interface SubscriptionService { - - Link add(Long chatId, URI url); - Link remove(Long chatId, URI url); - - List getAllByUser(Long chatId); - -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java deleted file mode 100644 index adf1fde..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/contract/TgChatService.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.contract; - -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; - -public interface TgChatService { - - void register(User user); - - void unregister(Long chatId); - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java deleted file mode 100644 index 983fdb9..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/LinkUpdateServiceImpl.java +++ /dev/null @@ -1,156 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; -import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; -import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; -import ru.tinkoff.edu.java.scrapper.client.BotClient; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; -import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; -import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; -import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; -import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; -//import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -//import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; -//import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; -//import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -//import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; - -import java.sql.Timestamp; -import java.time.ZoneOffset; -import java.util.List; - -@Slf4j -public class LinkUpdateServiceImpl implements LinkUpdateService { - - - @Value("${update.delta.time}") - private Long timeUpdateDeltaInSeconds; - - private final LinkRepository linkRepository; - - private final SubscriptionRepository subscriptionRepository; - - private final Link_Parser linkParser; - - private final GitHubClient gitHubClient; - - private final StackOverflowClient stackOverflowClient; - - private final BotClient botClient; - - - public LinkUpdateServiceImpl(LinkRepository linkRepository, SubscriptionRepository subscriptionRepository, Link_Parser linkParser, GitHubClient gitHubClient, StackOverflowClient stackOverflowClient, BotClient botClient) { - this.linkRepository = linkRepository; - this.subscriptionRepository = subscriptionRepository; - this.linkParser = linkParser; - this.gitHubClient = gitHubClient; - this.stackOverflowClient = stackOverflowClient; - this.botClient = botClient; - } - - @Override - public List getOldLinks() { - return linkRepository.findOldLinks(timeUpdateDeltaInSeconds); - } - - - public void updateLinks() { - List oldLinks = getOldLinks(); - - for (Link link : oldLinks) { - Parser_Link result = linkParser.parseUrl(link.getUrl()); - if (result instanceof GitHub_Link) { - try { - boolean isUpdated = false; - String updateDescription = ""; - - - GitHubResponse response = gitHubClient.fetchRepo(((GithubParseResult) result).username(), ((GithubParseResult) result).repository()); - - - if (response.forksCount() != link.getGhForksCount()) { - isUpdated = true; - if (response.forksCount() < link.getGhForksCount()) { - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ„ΠΎΡ€ΠΊΠΎΠ²\n"; - } - if (response.forksCount() > link.getGhForksCount()) { - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появились Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΠΎΡ€ΠΊΠΈ\n"; - } - link.setGhForksCount(response.forksCount()); - } - - - if (link.getGhDescription() == null || !response.description().equals(link.getGhDescription())) { - if (link.getGhDescription() != null) isUpdated = true; - link.setGhDescription(response.description()); - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ измСнилось описаниС\n"; - } - - if (link.getGhPushedAt() == null || response.pushedAt().toInstant().isAfter(link.getGhPushedAt().toInstant())) { - if (link.getGhPushedAt() != null) isUpdated = true; - link.setGhPushedAt(new Timestamp(response.pushedAt().toInstant().toEpochMilli())); - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появился Π½ΠΎΠ²Ρ‹ΠΉ commit\n"; - } - - - linkRepository.updateCheckDate(link); - - if (isUpdated) { - Long[] chats = subscriptionRepository.findChatsByLink(link.getId()).stream().map(Relation::getChatId).toArray(Long[]::new); - botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ:\n"+updateDescription, chats)); - } - - - } catch (GitHubRequestException e) { - log.warn(e.getMessage()); - } - - } else if (result instanceof StackOverflow_Link) { - try { - - boolean isUpdated = false; - String updateDescription = ""; - - - StackOverflowItem response = stackOverflowClient.fetchQuestion(((StackOverflowParseResult) result).id()); - - - if (response.lastEditDate() != null && (link.getSoLastEditDate() == null || response.lastEditDate().isAfter(link.getSoLastEditDate().toLocalDateTime().atOffset(ZoneOffset.UTC)))) { - if (link.getSoLastEditDate() != null) isUpdated = true; - link.setSoLastEditDate(new Timestamp(response.lastEditDate().toInstant().toEpochMilli())); - updateDescription += "ВСкст вопроса Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½\n"; - } - - if (response.answerCount() != link.getSoAnswerCount()) { - isUpdated = true; - if (response.answerCount() < link.getSoAnswerCount()) { - updateDescription += "На вопрос ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²\n"; - } - if (response.answerCount() > link.getSoAnswerCount()) { - updateDescription += "На вопрос появились Π½ΠΎΠ²Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹\n"; - } - link.setSoAnswerCount(response.answerCount()); - } - - linkRepository.updateCheckDate(link); - - if (isUpdated) { - - Long[] chats = subscriptionRepository.findChatsByLink(link.getId()).stream().map(Relation::getChatId).toArray(Long[]::new); - botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² вопросС:\n"+updateDescription, chats)); - } - - } catch (StackOverflowRequestException e) { - log.warn(e.getMessage()); - } - } - } - } -} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java deleted file mode 100644 index 4476e8b..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/SubscriptionServiceImpl.java +++ /dev/null @@ -1,99 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.model.jdbcAndJooq.Relation; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.LinkRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; - -import java.net.URI; -import java.sql.Timestamp; -import java.util.List; - - -@Slf4j -public class SubscriptionServiceImpl implements SubscriptionService { - - - private final LinkRepository linkRepository; - - private final SubscriptionRepository subscriptionRepository; - - - - public SubscriptionServiceImpl(LinkRepository linkRepository, SubscriptionRepository subscriptionRepository) { - this.linkRepository = linkRepository; - this.subscriptionRepository = subscriptionRepository; - } - - @Override - @Transactional - public Link subscribe(Long chatId, URI url) { - log.info("subscribe() method invocation in SubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); - Link link = linkRepository.findByUrl(url.toString()); - if (link == null) { - link = new Link(); - link.setUrl(url.toString()); - link.setCheckedAt(new Timestamp(System.currentTimeMillis())); - linkRepository.add(link); - //ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Π½ΠΈΠΆΠ΅ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ id ΠΈΠ· Π‘Π” - link = linkRepository.findByUrl(link.getUrl()); - } - Relation relation = subscriptionRepository.findSubscription(link.getId(), chatId); - - if (relation == null) { - relation = new Relation(); - relation.setChatId(chatId); - relation.setLinkId(link.getId()); - subscriptionRepository.addRelation(relation); - } - return link; - } - - @Override - @Transactional - public Link unsubscribe(Long chatId, URI url) { - log.info("unsubscribe() method invocation in SubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); - Link link = linkRepository.findByUrl(url.toString()); - - if (link != null) { -// linkRepository.remove(link.getId()); - subscriptionRepository.remove(link.getId(), chatId); - } - return link; - } - - @Override - public List getLinksByChat(Long chatId) { - log.info("getLinksByChat() method invocation in SubscriptionServiceImpl. chatId = "+chatId); - return subscriptionRepository.findLinksByChat(chatId); - } - - @Override - public List getChatIdsByLink(Long linkId) { - log.info("getChatIdsByLink() method invocation in SubscriptionServiceImpl. linkId = "+linkId); - return null; - } - - @Override - public Link add(Long chatId, URI url) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Link remove(Long chatId, URI url) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getAllByUser(Long chatId) { - // TODO Auto-generated method stub - return null; - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java deleted file mode 100644 index 84a130a..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jdbcAndJooq/impl/TgChatServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jdbcAndJooq.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.SubscriptionRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbcAndJooqContract.UserRepository; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; - -@Slf4j -public class TgChatServiceImpl implements TgChatService { - - private final UserRepository userRepository; - - private final SubscriptionRepository subscriptionRepository; - - - public TgChatServiceImpl(UserRepository userRepository, SubscriptionRepository subscriptionRepository) { - this.userRepository = userRepository; - this.subscriptionRepository = subscriptionRepository; - } - - @Override - public void register(User user) { - log.info("register() method invocation in TgChatServiceImpl. chatId = "+user.getChatId()); - User userInBd = userRepository.findByChatId(user.getChatId()); - if (userInBd != null) throw new ChatAlreadyExistException(); - userRepository.add(user); - } - - @Override - @Transactional - public void unregister(Long chatId) { - log.info("unregister() method invocation in TgChatServiceImpl. chatId = "+chatId); - userRepository.remove(chatId); - subscriptionRepository.removeAllByUser(chatId); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java deleted file mode 100644 index f27d081..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaLinkUpdateServiceImpl.java +++ /dev/null @@ -1,174 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jpa.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.link_parser.parser.Link_Parser; -import ru.tinkoff.edu.java.link_parser.link.GitHub_Link; -import ru.tinkoff.edu.java.link_parser.link.Parser_Link; -import ru.tinkoff.edu.java.link_parser.link.StackOverflow_Link; -import ru.tinkoff.edu.java.scrapper.client.BotClient; -import ru.tinkoff.edu.java.scrapper.client.GitHubClient; -import ru.tinkoff.edu.java.scrapper.client.StackOverflowClient; -import ru.tinkoff.edu.java.scrapper.dto.GitHubResponse; -import ru.tinkoff.edu.java.scrapper.dto.LinkUpdate; -import ru.tinkoff.edu.java.scrapper.dto.StackOverflowItem; -import ru.tinkoff.edu.java.scrapper.exception.GitHubRequestException; -import ru.tinkoff.edu.java.scrapper.exception.StackOverflowRequestException; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; -import ru.tinkoff.edu.java.scrapper.service.contract.LinkUpdateService; - -import java.sql.Timestamp; -import java.time.ZoneOffset; -import java.util.List; - -@Slf4j -public class JpaLinkUpdateServiceImpl implements LinkUpdateService { - - @Value("${update.delta.time}") - private Long timeUpdateDeltaInSeconds; - - private final JpaLinkRepository linkRepository; - - - - private final Link_Parser linkParser; - - private final GitHubClient gitHubClient; - - private final StackOverflowClient stackOverflowClient; - - private final BotClient botClient; - - - public JpaLinkUpdateServiceImpl(JpaLinkRepository linkRepository, LinkParser linkParser, GitHubClient gitHubClient, StackOverflowClient stackOverflowClient, BotClient botClient) { - this.linkRepository = linkRepository; - this.linkParser = linkParser; - this.gitHubClient = gitHubClient; - this.stackOverflowClient = stackOverflowClient; - this.botClient = botClient; - } - - @Override - public List getOldLinks() { - log.info("getOldLinks() method invocation in JpaLinkUpdateServiceImpl"); - Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds*1000); - return linkRepository.findByCheckedAtLessThanOrderByCheckedAtDesc(compareDate).stream().map(Link::fromEntity).toList(); - } - - - public List getOldEntityLinks() { - Timestamp compareDate = new Timestamp(System.currentTimeMillis() - timeUpdateDeltaInSeconds*1000); - return linkRepository.findByCheckedAtLessThanOrderByCheckedAtDesc(compareDate); - } - - @Override - @Transactional - public void updateLinks() { - log.info("updateLinks() method invocation in JpaLinkUpdateServiceImpl"); - List oldLinks = getOldEntityLinks(); - - for (LinkEntity link : oldLinks) { - Parser_Link result = linkParser.parseUrl(link.getUrl()); - if (result instanceof GitHub_Link) { - try { - boolean isUpdated = false; - String updateDescription = ""; - - - System.out.println(link.getUrl()); - GitHubResponse response = gitHubClient.fetchRepo(((GitHub_Link) result).username(), ((GithubParseResult) result).repository()); - System.out.println(response); - - - if (link.getGhForksCount() == null || response.forksCount() != link.getGhForksCount()) { - isUpdated = true; - if (link.getGhForksCount() == null) {link.setGhForksCount(0); isUpdated = false;} - if (isUpdated && response.forksCount() < link.getGhForksCount()) { - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ„ΠΎΡ€ΠΊΠΎΠ²\n"; - } - if (isUpdated && response.forksCount() > link.getGhForksCount()) { - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появились Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΠΎΡ€ΠΊΠΈ\n"; - } - link.setGhForksCount(response.forksCount()); - } - - - if (link.getGhDescription() == null || !response.description().equals(link.getGhDescription())) { - if (link.getGhDescription() != null) isUpdated = true; - link.setGhDescription(response.description()); - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ измСнилось описаниС\n"; - } - - if (link.getGhPushedAt() == null || response.pushedAt().toInstant().isAfter(link.getGhPushedAt().toInstant())) { - if (link.getGhPushedAt() != null) isUpdated = true; - link.setGhPushedAt(new Timestamp(response.pushedAt().toInstant().toEpochMilli())); - updateDescription += "Π’ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ появился Π½ΠΎΠ²Ρ‹ΠΉ commit\n"; - } - - link.setCheckedAt(new Timestamp(System.currentTimeMillis())); - - linkRepository.save(link); - - if (isUpdated) { - List chatsIds = linkRepository.findChatIdsByLinkId(link.getId()); - botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ:\n"+updateDescription, chatsIds.toArray(new Long[0]))); - } - - - } catch (GitHubRequestException e) { - log.warn(e.getMessage()); - } - - } else if (result instanceof StackOverflow_Link) { - try { - - boolean isUpdated = false; - String updateDescription = ""; - - - System.out.println(link.getUrl()); - StackOverflowItem response = stackOverflowClient.fetchQuestion(((StackOverflowParseResult) result).id()); - System.out.println(response); - - - - if (response.lastEditDate() != null && (link.getSoLastEditDate() == null || response.lastEditDate().isAfter(link.getSoLastEditDate().toLocalDateTime().atOffset(ZoneOffset.UTC)))) { - if (link.getSoLastEditDate() != null) isUpdated = true; - link.setSoLastEditDate(new Timestamp(response.lastEditDate().toInstant().toEpochMilli())); - updateDescription += "ВСкст вопроса Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½\n"; - } - - if (link.getSoAnswerCount() == null || response.answerCount() != link.getSoAnswerCount()) { - isUpdated = true; - if (link.getSoAnswerCount() == null) {link.setSoAnswerCount(0); isUpdated = false;} - if (isUpdated && response.answerCount() < link.getSoAnswerCount()) { - updateDescription += "На вопрос ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ»ΠΎΡΡŒ ΠΊΠΎΠ»-Π²ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²\n"; - } - if (isUpdated && response.answerCount() > link.getSoAnswerCount()) { - updateDescription += "На вопрос появились Π½ΠΎΠ²Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹\n"; - } - link.setSoAnswerCount(response.answerCount()); - } - - - link.setCheckedAt(new Timestamp(System.currentTimeMillis())); - - linkRepository.save(link); - - if (isUpdated) { - List chatsIds = linkRepository.findChatIdsByLinkId(link.getId()); - botClient.updateLink(new LinkUpdate(link.getId(), link.getUrl(), "Π’Ρ‹ΡˆΠ»ΠΈ обновлСния Π² вопросС:\n"+updateDescription, chatsIds.toArray(new Long[0]))); - } - - } catch (StackOverflowRequestException e) { - log.warn(e.getMessage()); - } - } - } - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java deleted file mode 100644 index c5c9749..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaSubscriptionServiceImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jpa.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; -import ru.tinkoff.edu.java.scrapper.exception.LinkNotFoundException; -import ru.tinkoff.edu.java.scrapper.model.commonDto.Link; -import ru.tinkoff.edu.java.scrapper.model.jpa.LinkEntity; -import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaLinkRepository; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; -import ru.tinkoff.edu.java.scrapper.service.contract.SubscriptionService; - -import java.net.URI; -import java.sql.Timestamp; -import java.util.List; -import java.util.Optional; - -@Slf4j -public class JpaSubscriptionServiceImpl implements SubscriptionService { - - private final JpaLinkRepository linkRepository; - - private final JpaUserRepository userRepository; - - public JpaSubscriptionServiceImpl(JpaLinkRepository linkRepository, JpaUserRepository userRepository) { - this.linkRepository = linkRepository; - this.userRepository = userRepository; - } - - - @Override - @Transactional - public Link subscribe(Long chatId, URI url) { - log.info("subscribe() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); - Optional optionalLink = linkRepository.findByUrl(url.toString()); - LinkEntity linkToAdd = new LinkEntity(); - if (optionalLink.isEmpty()) { - linkToAdd.setUrl(url.toString()); - } else { - linkToAdd = optionalLink.get(); - } - linkToAdd.setCheckedAt(new Timestamp(System.currentTimeMillis())); - linkRepository.save(linkToAdd); - - Optional optionalUser = userRepository.findById(chatId); - if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); - UserEntity user = optionalUser.get(); - List userLinks = user.getLinks(); - - if (!userLinks.contains(linkToAdd)) { - userLinks.add(linkToAdd); - } - - userRepository.save(user); - return Link.fromEntity(linkToAdd); - } - - @Override - @Transactional - public Link unsubscribe(Long chatId, URI url) { - log.info("unsubscribe() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId+" url = "+url.toString()); - Optional optionalUser = userRepository.findByChatIdWithLinks(chatId); - Optional optionalLink = linkRepository.findByUrl(url.toString()); - - - if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ зарСгистрирован"); - - UserEntity user = optionalUser.get(); - - List userLinks = user.getLinks(); - - if (optionalLink.isEmpty() || !userLinks.contains(optionalLink.get())) - throw new LinkNotFoundException("Вакая ссылка Π½Π΅ отслСТиваСтся"); - - userLinks.remove(optionalLink.get()); - userRepository.save(user); - - return Link.fromEntity(optionalLink.get()); - } - - @Override - public List getLinksByChat(Long chatId) { - log.info("getAllByUser() method invocation in JpaSubscriptionServiceImpl. chatId = "+chatId); - Optional optionalUser = userRepository.findById(chatId); - if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); - return userRepository.findAllLinksByChat(chatId).stream().map(Link::fromEntity).toList(); - } - - - @Override - public List getChatIdsByLink(Long linkId) { - log.info("getChatIdsByLink() method invocation in JpaSubscriptionServiceImpl. linkId = "+linkId); - Optional optionalLink = linkRepository.findById(linkId); - if (optionalLink.isEmpty()) throw new LinkNotFoundException("Вакая ссылка Π½Π΅ отслСТиваСтся"); - return linkRepository.findChatIdsByLinkId(linkId); - } -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java b/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java deleted file mode 100644 index b87e274..0000000 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/service/jpa/impl/JpaTgChatServiceImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.tinkoff.edu.java.scrapper.service.jpa.impl; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import ru.tinkoff.edu.java.scrapper.exception.ChatAlreadyExistException; -import ru.tinkoff.edu.java.scrapper.exception.ChatNotFoundException; -import ru.tinkoff.edu.java.scrapper.model.commonDto.User; -import ru.tinkoff.edu.java.scrapper.model.jpa.UserEntity; -import ru.tinkoff.edu.java.scrapper.repository.jpa.JpaUserRepository; -import ru.tinkoff.edu.java.scrapper.service.contract.TgChatService; - -import java.util.Optional; - - -@Slf4j -public class JpaTgChatServiceImpl implements TgChatService { - - private final JpaUserRepository userRepository; - - public JpaTgChatServiceImpl(JpaUserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - public void register(User user) { - log.info("register() method invocation in JpaTgChatServiceImpl. User chatId = "+user.getChatId()); - Optional optionalUser = userRepository.findById(user.getChatId()); - if (optionalUser.isPresent()) throw new ChatAlreadyExistException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ ΡƒΠΆΠ΅ зарСгистрирован!"); - userRepository.save(User.toEntity(user)); - } - - @Override - public void unregister(Long chatId) { - log.info("unregister() method invocation in JpaTgChatServiceImpl. User chatId = "+chatId); - Optional optionalUser = userRepository.findById(chatId); - if (optionalUser.isEmpty()) throw new ChatNotFoundException("Π’Π°ΠΊΠΎΠΉ Ρ‡Π°Ρ‚ Π½Π΅ зарСгистрирован!"); - userRepository.delete(optionalUser.get()); - } - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/main/resources/application.properties b/FP/FP/scrapper/src/main/resources/application.properties deleted file mode 100644 index 3761f00..0000000 --- a/FP/FP/scrapper/src/main/resources/application.properties +++ /dev/null @@ -1,23 +0,0 @@ -server.port=8080 -app.test=beamer-scrapper -gh.baseurl=https://api.github.com -so.baseurl=https://api.stackexchange.com/2.3/ -bot.baseurl=http://localhost:8081 -app.scheduler.interval=61000 -update.delta.time=20 -springdoc.swagger-ui.path=/swagger-ui - -spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost:5432/scrapper -spring.datasource.username=romanova -spring.datasource.password=12345654321 -spring.jpa.properties.hibernate.show_sql=true - -spring.rabbitmq.host=localhost -spring.rabbitmq.port=5672 -spring.rabbitmq.username=romanova -spring.rabbitmq.password=12345654321 -app.queue-name=scrapper-bot-queue -app.exchange-name=scrapper-bot-exchange -app.routing-key=scrapper-bot-key -app.use-queue=true diff --git a/FP/FP/scrapper/src/main/resources/logback-test.xml b/FP/FP/scrapper/src/main/resources/logback-test.xml deleted file mode 100644 index 900637e..0000000 --- a/FP/FP/scrapper/src/main/resources/logback-test.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n - - - - - - - - - - - - -. diff --git a/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java b/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java deleted file mode 100644 index 1c2378c..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/DatabaseTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package scrapper; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.sql.*; - -public class DatabaseTest extends IntegrationEnvironment{ - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° с PostgreSQL") - public void testIfContainerIsRunning() { - Assertions.assertTrue(POSTGRES_CONTAINER.isRunning(),"Ошибка запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° PostgreSQL"); - } - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ примСнСния ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ") - void testMigrations() throws SQLException { - try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), - IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), - IntegrationEnvironment.POSTGRES_CONTAINER.getPassword()); - Statement statement = conn.createStatement()) { - - ResultSet resultSetUser = statement.executeQuery("SELECT * FROM \"user\""); - Assertions.assertFalse(resultSetUser.next(), "Π’Π°Π±Π»ΠΈΡ†Π° user Π½Π΅ создана"); - ResultSet resultSetLink = statement.executeQuery("SELECT * FROM \"link\""); - Assertions.assertFalse(resultSetLink.next(), "Π’Π°Π±Π»ΠΈΡ†Π° link Π½Π΅ создана"); - ResultSet resultSetUserLink = statement.executeQuery("SELECT * FROM \"user_link\""); - Assertions.assertFalse(resultSetUserLink.next(),"Π’Π°Π±Π»ΠΈΡ†Π° user_link Π½Π΅ создана"); - } - } - - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java b/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java deleted file mode 100644 index 2f0bdfa..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/IntegrationEnvironment.java +++ /dev/null @@ -1,54 +0,0 @@ -package scrapper; - -import liquibase.Contexts; -import liquibase.LabelExpression; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.LiquibaseException; -import liquibase.resource.DirectoryResourceAccessor; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Testcontainers; - -import java.io.File; -import java.io.FileNotFoundException; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -abstract class IntegrationEnvironment { - - static final String IMAGE_VERSION = "postgres:15"; - - static final PostgreSQLContainer POSTGRES_CONTAINER; - - static { - POSTGRES_CONTAINER = new PostgreSQLContainer(IMAGE_VERSION) - .withDatabaseName("scrapper") - .withUsername("lwbeamer") - .withPassword("2281337"); - - - POSTGRES_CONTAINER.start(); - executeMigrations(); - } - - private static void executeMigrations() { - try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), - IntegrationEnvironment.POSTGRES_CONTAINER.getPassword())) { - Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); - Path changeLogFile = new File("").toPath().toAbsolutePath().getParent().resolve("migrations"); - Liquibase liquibase = new Liquibase("master.xml",new DirectoryResourceAccessor(changeLogFile), database); - liquibase.update(new Contexts(), new LabelExpression()); - } catch (SQLException | LiquibaseException e) { - throw new RuntimeException("Failed to execute migrations", e); - } catch (FileNotFoundException e) { - throw new RuntimeException("Changelog file not found",e); - } - } - - public static void stopContainer() { - POSTGRES_CONTAINER.stop(); - } diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java b/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java deleted file mode 100644 index d0ac18a..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/environment/DatabaseTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package scrapper.environment; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.sql.*; - -public class DatabaseTest extends IntegrationEnvironment{ - - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° с PostgreSQL") - public void testIfContainerIsRunning() { - Assertions.assertTrue(POSTGRES_CONTAINER.isRunning(),"Ошибка запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° PostgreSQL"); - } - - @Test - @DisplayName("ВСст для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ примСнСния ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ") - void testMigrations() throws SQLException { - try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), - IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), - IntegrationEnvironment.POSTGRES_CONTAINER.getPassword()); - Statement statement = conn.createStatement()) { - - ResultSet resultSetUser = statement.executeQuery("SELECT * FROM \"user\""); - Assertions.assertFalse(resultSetUser.next(), "Π’Π°Π±Π»ΠΈΡ†Π° user Π½Π΅ создана"); - ResultSet resultSetLink = statement.executeQuery("SELECT * FROM \"link\""); - Assertions.assertFalse(resultSetLink.next(), "Π’Π°Π±Π»ΠΈΡ†Π° link Π½Π΅ создана"); - ResultSet resultSetUserLink = statement.executeQuery("SELECT * FROM \"user_link\""); - Assertions.assertFalse(resultSetUserLink.next(),"Π’Π°Π±Π»ΠΈΡ†Π° user_link Π½Π΅ создана"); - } - } - - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java b/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java deleted file mode 100644 index 416b086..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/environment/IntegrationEnvironment.java +++ /dev/null @@ -1,81 +0,0 @@ -package scrapper.environment; - -import liquibase.Contexts; -import liquibase.LabelExpression; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.LiquibaseException; -import liquibase.resource.DirectoryResourceAccessor; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.context.ContextConfiguration; -import org.testcontainers.containers.PostgreSQLContainer; - -import javax.sql.DataSource; -import java.io.File; -import java.io.FileNotFoundException; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -@ContextConfiguration(classes = IntegrationEnvironment.EnvironmentConfiguration.class) -public abstract class IntegrationEnvironment { - - - @Configuration - static class EnvironmentConfiguration{ - @Bean - public DataSource dataSource() { - return DataSourceBuilder.create() - .url(POSTGRES_CONTAINER.getJdbcUrl()) - .username(POSTGRES_CONTAINER.getUsername()) - .password(POSTGRES_CONTAINER.getPassword()) - .build(); - } - - @Bean - public JdbcTemplate jdbcTemplate(DataSource dataSource){ - return new JdbcTemplate(dataSource); - } - - } - - static final String IMAGE_VERSION = "postgres:15"; - - static final PostgreSQLContainer POSTGRES_CONTAINER; - - static { - POSTGRES_CONTAINER = new PostgreSQLContainer(IMAGE_VERSION) - .withDatabaseName("scrapper") - .withUsername("lwbeamer") - .withPassword("2281337"); - - - POSTGRES_CONTAINER.start(); - executeMigrations(); - } - - private static void executeMigrations() { - try (Connection conn = DriverManager.getConnection(IntegrationEnvironment.POSTGRES_CONTAINER.getJdbcUrl(), IntegrationEnvironment.POSTGRES_CONTAINER.getUsername(), - IntegrationEnvironment.POSTGRES_CONTAINER.getPassword())) { - Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); - Path changeLogFile = new File("").toPath().toAbsolutePath().getParent().resolve("migrations"); - Liquibase liquibase = new Liquibase("master.xml",new DirectoryResourceAccessor(changeLogFile), database); - liquibase.update(new Contexts(), new LabelExpression()); - } catch (SQLException | LiquibaseException e) { - throw new RuntimeException("Failed to execute migrations", e); - } catch (FileNotFoundException e) { - throw new RuntimeException("Changelog file not found",e); - } - } - - public static void stopContainer() { - POSTGRES_CONTAINER.stop(); - } - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java b/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java deleted file mode 100644 index a4ff395..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/environment/TestConfiguration.java +++ /dev/null @@ -1,8 +0,0 @@ -package scrapper.environment; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; - -@EnableAutoConfiguration(exclude = { LiquibaseAutoConfiguration.class }) -public class TestConfiguration { -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java deleted file mode 100644 index 436f01a..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcLinkTest.java +++ /dev/null @@ -1,151 +0,0 @@ -package scrapper.jdbc; - -import scrapper.environment.IntegrationEnvironment; -import scrapper.environment.TestConfiguration; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.annotation.Rollback; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.ScrapperApplication; -import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; -import ru.tinkoff.edu.java.scrapper.model.Link; -import ru.tinkoff.edu.java.scrapper.repository.*; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; - -import java.sql.Timestamp; -import java.util.List; - -@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) -public class JdbcLinkTest extends IntegrationEnvironment { - - @Autowired - private LinkJdbcTemplateRepository linkRepository; - - @Autowired - private LinkRowMapper linkRowMapper; - - @Autowired - private JdbcTemplate jdbcTemplate; - - - @Test - @Transactional - @Rollback - public void addLinkTest() { - List beforeAddLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); - - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - linkRepository.add(linkToAdd); - - List addedLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertNotNull(addedLink.get(0)); - Assertions.assertEquals("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file", addedLink.get(0).getUrl()); - } - - - @Test - @Transactional - @Rollback - public void removeLinkTest() { - List beforeAddLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); - - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - - List afterInsertionLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); - - linkRepository.remove(afterInsertionLink.get(0).getId()); - - List afterRemovingLink = jdbcTemplate.query("select * from link where link.url='https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file'", linkRowMapper); - - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 1); - Assertions.assertEquals(afterRemovingLink.size(), 0); - } - - - @Test - @Transactional - @Rollback - public void findAllTest() { - List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); - - for (int i = 0; i < 10; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = linkRepository.findAll(); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 10); - } - - - @Test - @Transactional - @Rollback - public void findByUrlTest(){ - List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); - - for (int i = 0; i < 10; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - Link foundedByUrlLink = linkRepository.findByUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file0"); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 10); - Assertions.assertNotNull(foundedByUrlLink); - } - - - @Test - @Transactional - @Rollback - public void updateDateTest(){ - List beforeAddLink = jdbcTemplate.query("select * from link", linkRowMapper); - - - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); - linkToAdd.setUpdatedAt(timestampBefore); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - - - List linkBeforeUpdate = jdbcTemplate.query("select * from link where link.url = ?", linkRowMapper, "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - - Assertions.assertEquals(linkBeforeUpdate.get(0).getUpdatedAt(),timestampBefore); - - linkBeforeUpdate.get(0).setUpdatedAt(new Timestamp(100000)); - - linkRepository.updateDate(linkBeforeUpdate.get(0)); - - List linkAfterUpdate = jdbcTemplate.query("select * from link where link.url = ?", linkRowMapper, "https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(linkAfterUpdate.get(0).getUpdatedAt(),new Timestamp(100000)); - } - - - - - -} \ No newline at end of file diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java deleted file mode 100644 index 0813c59..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcSubscriptionTest.java +++ /dev/null @@ -1,251 +0,0 @@ -package scrapper.jdbc; - -import scrapper.environment.IntegrationEnvironment; -import scrapper.environment.TestConfiguration; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.annotation.Rollback; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.ScrapperApplication; -import ru.tinkoff.edu.java.scrapper.mapper.LinkRowMapper; -import ru.tinkoff.edu.java.scrapper.mapper.SubscriptionRowMapper; -import ru.tinkoff.edu.java.scrapper.model.Link; -import ru.tinkoff.edu.java.scrapper.model.Relation; -import ru.tinkoff.edu.java.scrapper.model.User; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.LinkJdbcTemplateRepository; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.SubscriptionJdbcTemplateRepository; - -import java.sql.Timestamp; -import java.util.List; - -@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) -public class JdbcSubscriptionTest extends IntegrationEnvironment { - - @Autowired - private SubscriptionJdbcTemplateRepository subscriptionRepository; - - @Autowired - private LinkRowMapper linkRowMapper; - - @Autowired - private SubscriptionRowMapper subscriptionRowMapper; - - @Autowired - private JdbcTemplate jdbcTemplate; - - - @Test - @Transactional - @Rollback - public void findLinksByChatTest() { - List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 50L, "alucard", "Will", "Smith"); - - //всСго Π΄ΠΎΠ±Π°Π²ΠΈΠΌ 20 ссылок - for (int i = 0; i < 20; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - - //ΠΈΠ· 20-Ρ‚ΠΈ ссылок подпишСмся лишь Π½Π° 10 - for (int i = 0; i < 10; i++) { - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); - } - - //Π½Π° ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ 10 подпишСм Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ - for (int i = 10; i < 20; i++) { - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 50L); - } - - List userLinks = subscriptionRepository.findLinksByChat(42L); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 20); - Assertions.assertEquals(userLinks.size(), 10); - } - - @Test - @Transactional - @Rollback - public void removeRelationTest() { - List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); - - for (int i = 0; i < 20; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - - for (int i = 0; i < 10; i++) { - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); - } - - List userLinksBeforeRemove = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - subscriptionRepository.remove(afterInsertionLink.get(0).getId(), 42L); - subscriptionRepository.remove(afterInsertionLink.get(4).getId(), 42L); - subscriptionRepository.remove(afterInsertionLink.get(6).getId(), 42L); - - List userLinksAfterRemove = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 20); - Assertions.assertEquals(userLinksBeforeRemove.size(), 10); - Assertions.assertEquals(userLinksAfterRemove.size(), 7); - } - - - @Test - @Transactional - @Rollback - public void addRelationTest() { - List beforeAddLink = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); - - for (int i = 0; i < 20; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - - for (int i = 0; i < 10; i++) { - Relation relation = new Relation(); - relation.setLinkId(afterInsertionLink.get(i).getId()); - relation.setChatId(42L); - subscriptionRepository.addRelation(relation); - } - - - List userLinks = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - Assertions.assertEquals(beforeAddLink.size(), 0); - Assertions.assertEquals(afterInsertionLink.size(), 20); - Assertions.assertEquals(userLinks.size(), 10); - } - - - @Test - @Transactional - @Rollback - public void findChatsByLinkTest() { - List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); - - - for (int i = 0; i < 10; i++) { - User user = new User(42L + i, "robtop21" + i, "Robert", "Polson"); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", - user.getChatId(), - user.getUsername(), - user.getFirstName(), - user.getLastName()); - } - - - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - - - for (int i = 0; i < 7; i++) { - Relation relation = new Relation(); - relation.setLinkId(afterInsertionLink.get(0).getId()); - relation.setChatId(42L + i); - subscriptionRepository.addRelation(relation); - } - - List afterSubscribe = subscriptionRepository.findChatsByLink(afterInsertionLink.get(0).getId()); - - Assertions.assertEquals(beforeAddRelation.size(), 0); - Assertions.assertEquals(afterSubscribe.size(), 7); - } - - @Test - @Transactional - @Rollback - public void findSubscriptionTest() { - List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); - - - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file"); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(0).getId(), 42L); - - Relation relation = subscriptionRepository.findSubscription(afterInsertionLink.get(0).getId(), 42L); - - - Assertions.assertEquals(beforeAddRelation.size(),0); - Assertions.assertEquals(afterInsertionLink.size(),1); - Assertions.assertNotNull(relation); - } - - - @Test - @Transactional - @Rollback - public void removeAllByUserTest(){ - List beforeAddRelation = jdbcTemplate.query("select * from user_link", subscriptionRowMapper); - - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 42L, "robtop21", "Robert", "Polson"); - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", 50L, "alucard", "Will", "Smith"); - - //всСго Π΄ΠΎΠ±Π°Π²ΠΈΠΌ 20 ссылок - for (int i = 0; i < 20; i++) { - Link linkToAdd = new Link(); - linkToAdd.setUrl("https://stackoverflow.com/questions/2336692/java-multiple-class-declarations-in-one-file" + i); - linkToAdd.setUpdatedAt(new Timestamp(System.currentTimeMillis())); - jdbcTemplate.update("insert into link (url, updated_at) values(?, ?)", linkToAdd.getUrl(), linkToAdd.getUpdatedAt()); - } - - List afterInsertionLink = jdbcTemplate.query("select * from link", linkRowMapper); - - //ΠΈΠ· 20-Ρ‚ΠΈ ссылок подпишСмся лишь Π½Π° 10 - for (int i = 0; i < 10; i++) { - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 42L); - } - - //Π½Π° ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ 10 подпишСм Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ - for (int i = 10; i < 20; i++) { - jdbcTemplate.update("insert into user_link (link_id, chat_id) values(?, ?)", afterInsertionLink.get(i).getId(), 50L); - } - - List userLinksBeforeDelete = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - subscriptionRepository.removeAllByUser(42L); - - List userLinksAfterDelete = jdbcTemplate.query("select * from link inner join user_link rel on link.id = rel.link_id where rel.chat_id = ?", linkRowMapper, 42L); - - Assertions.assertEquals(beforeAddRelation.size(),0); - Assertions.assertEquals(afterInsertionLink.size(), 20); - Assertions.assertEquals(userLinksBeforeDelete.size(), 10); - Assertions.assertEquals(userLinksAfterDelete.size(), 0); - } - -} diff --git a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java b/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java deleted file mode 100644 index df7d245..0000000 --- a/FP/FP/scrapper/src/test/java/scrapper/jdbc/JdbcUserTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package scrapper.jdbc; - -import scrapper.environment.IntegrationEnvironment; -import scrapper.environment.TestConfiguration; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.annotation.Rollback; -import org.springframework.transaction.annotation.Transactional; -import ru.tinkoff.edu.java.scrapper.ScrapperApplication; -import ru.tinkoff.edu.java.scrapper.mapper.UserRowMapper; -import ru.tinkoff.edu.java.scrapper.model.User; -import ru.tinkoff.edu.java.scrapper.repository.jdbc.UserJdbcTemplateRepository; - -import java.util.List; - -@SpringBootTest(classes = {ScrapperApplication.class, TestConfiguration.class}) -public class JdbcUserTest extends IntegrationEnvironment { - - @Autowired - private UserJdbcTemplateRepository userRepository; - - @Autowired - private UserRowMapper userRowMapper; - - @Autowired - private JdbcTemplate jdbcTemplate; - - - @Test - @Transactional - @Rollback - public void addUserTest() { - List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - User user = new User(42L, "robtop21", "Robert","Polson"); - - - userRepository.add(user); - - List afterAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - Assertions.assertEquals(beforeAddUser.size(), 0); - Assertions.assertEquals(afterAddUser.size(), 1); - Assertions.assertNotNull(afterAddUser.get(0)); - Assertions.assertEquals(afterAddUser.get(0).getChatId(), 42L); - } - - - @Test - @Transactional - @Rollback - public void removeUserTest() { - List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - User user = new User(42L, "robtop21", "Robert","Polson"); - - - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", - user.getChatId(), - user.getUsername(), - user.getFirstName(), - user.getLastName()); - - - List afterAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - userRepository.remove(42L); - - List afterRemoveUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - - Assertions.assertEquals(beforeAddUser.size(), 0); - Assertions.assertEquals(afterAddUser.size(), 1); - Assertions.assertNotNull(afterAddUser.get(0)); - Assertions.assertEquals(afterAddUser.get(0).getChatId(), 42L); - Assertions.assertEquals(afterRemoveUser.size(), 0); - } - - @Test - @Transactional - @Rollback - public void findAllTest() { - List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - - for (int i = 0; i < 10; i++) { - User user = new User(42L + i, "robtop21" + i, "Robert","Polson"); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", - user.getChatId(), - user.getUsername(), - user.getFirstName(), - user.getLastName()); - } - - List afterInsertionUser = userRepository.findAll(); - - Assertions.assertEquals(beforeAddUser.size(), 0); - Assertions.assertEquals(afterInsertionUser.size(), 10); - } - - - @Test - @Transactional - @Rollback - public void findByChatIdTest(){ - List beforeAddUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - - for (int i = 0; i < 10; i++) { - User user = new User(42L + i, "robtop21" + i, "Robert","Polson"); - - jdbcTemplate.update("insert into \"user\" (chat_id, username, first_name, last_name) values(?, ?, ?, ?)", - user.getChatId(), - user.getUsername(), - user.getFirstName(), - user.getLastName()); - } - - List afterInsertionUser = jdbcTemplate.query("select * from \"user\"", userRowMapper); - - User foundedByIdUser = userRepository.findByChatId(42L); - - Assertions.assertEquals(beforeAddUser.size(), 0); - Assertions.assertEquals(afterInsertionUser.size(), 10); - Assertions.assertNotNull(foundedByIdUser); - - } - - -} \ No newline at end of file diff --git a/FP/bot/pom.xml b/FP/bot/pom.xml new file mode 100644 index 0000000..96dea0d --- /dev/null +++ b/FP/bot/pom.xml @@ -0,0 +1,110 @@ + + + + org.example + FP + 1.0 + + + 4.0.0 + + bot + + + 3.0.1 + 2.7.6 + + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.1.0 + + + org.apache.commons + commons-lang3 + 3.10 + + + + org.springframework.boot + spring-boot-starter-validation + ${starter-validation.version} + + + org.springframework.boot + spring-boot-starter-web + ${starter-web.version} + + + org.apache.logging.log4j + log4j-to-slf4j + + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework + spring-context-indexer + true + + + org.projectlombok + lombok + true + + + + com.github.pengrad + java-telegram-bot-api + 6.6.0 + + + + org.junit.jupiter + junit-jupiter + test + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + + org.springframework.boot + spring-boot-starter-amqp + 3.0.6 + + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.postgresql + postgresql + runtime + + + org.example + scrapper + 1.0 + compile + + + \ No newline at end of file diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java new file mode 100644 index 0000000..92ae210 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/BotApplication.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.bot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.bot.configuration.records.ApplicationConfig; +import ru.tinkoff.edu.java.bot.handler.BotMain; + +import javax.sql.DataSource; + + +@SpringBootApplication +@EnableConfigurationProperties(ApplicationConfig.class) +public class BotApplication +{ + public static void main(String[] args){ + var ctx = SpringApplication.run(BotApplication.class, args); + ApplicationConfig config = ctx.getBean(ApplicationConfig.class); + JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate"); + BotMain bot = new BotMain(config.bot().token(), jdbcTemplate); + bot.start(); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/BotController.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/BotController.java new file mode 100644 index 0000000..6a559cf --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/BotController.java @@ -0,0 +1,14 @@ +package ru.tinkoff.edu.java.bot.api; + +import org.springframework.web.bind.annotation.*; +import ru.tinkoff.edu.java.bot.model.LinkUpdate; + +@RestController +@RequestMapping("/update") +public class BotController { + + @PostMapping + public String updateChat(@RequestBody LinkUpdate update) { + return update.toString(); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/exceptionHandler/BotExceptionHandler.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/exceptionHandler/BotExceptionHandler.java new file mode 100644 index 0000000..5beb1bd --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/api/exceptionHandler/BotExceptionHandler.java @@ -0,0 +1,36 @@ +package ru.tinkoff.edu.java.bot.api.exceptionHandler; + +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.tinkoff.edu.java.bot.model.ApiErrorResponse; + +@RestControllerAdvice +public class BotExceptionHandler { + + private String getDescription(String message) { + ApiErrorResponse errorObj = new ApiErrorResponse( + message, + null, + null, + null, + null + ); + return errorObj.description(); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public String MessageNotReadable(HttpMessageNotReadableException Exception) { + return getDescription("НСкоррСктныС значСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈΠ»ΠΈ ΠΈΡ… Π½Π΅Ρ‚!"); + } + + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public String MethodNotSupported(HttpRequestMethodNotSupportedException Exception) { + return getDescription("ΠœΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½!"); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java new file mode 100644 index 0000000..1616669 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/RabbitMQConfiguration.java @@ -0,0 +1,56 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.bot.configuration.records.ApplicationConfig; + +import java.util.Collections; + +@Configuration +public class RabbitMQConfiguration { + + private final ApplicationConfig config; + + public RabbitMQConfiguration(ApplicationConfig config) { + this.config = config; + } + + @Bean + public DirectExchange exchange() { + return new DirectExchange(config.exchange()); + } + + @Bean + public Queue queue() { + return QueueBuilder.durable(config.queue()) + .withArgument("x-dead-letter-exchange",config.queue() + ".dlq") + .build(); + } + + @Bean + public Binding binding(Queue queue, DirectExchange exchange) { + return BindingBuilder.bind(queue) + .to(exchange) + .with(config.routingKey()); + } + + @Bean + public DirectExchange dlqExchange() { + return new DirectExchange(config.exchange() + ".dlq"); + } + + @Bean + public Queue dlqQueue() { + return QueueBuilder.durable(config.queue() + ".dlq").build(); + } + + @Bean + public Binding dlqBinding() { + return BindingBuilder.bind(dlqQueue()) + .to(dlqExchange()) + .with(config.routingKey()); + } +} \ No newline at end of file diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/jdbcBean.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/jdbcBean.java new file mode 100644 index 0000000..e768de5 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/jdbcBean.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.bot.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import javax.sql.DataSource; + +@Configuration +public class jdbcBean { + @Bean + public DataSource dataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("org.postgresql.Driver"); + dataSource.setUrl("jdbc:postgresql://localhost:5432/postgres"); + dataSource.setUsername("scrap_user"); + dataSource.setPassword("hard_password"); + + return dataSource; + } + @Bean + public JdbcTemplate jdbcTemplate () { + return new JdbcTemplate (dataSource()); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/ApplicationConfig.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/ApplicationConfig.java new file mode 100644 index 0000000..c23d07b --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/ApplicationConfig.java @@ -0,0 +1,22 @@ +package ru.tinkoff.edu.java.bot.configuration.records; + +import jakarta.validation.constraints.NotNull; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.validation.annotation.Validated; + +@Validated +@EnableScheduling +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) +public record ApplicationConfig( + @NotNull String test, + @NotNull Scheduler scheduler, + String exchange, + String routingKey, + String queue, + Bot bot +) { +} \ No newline at end of file diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Bot.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Bot.java new file mode 100644 index 0000000..0a1fff4 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Bot.java @@ -0,0 +1,4 @@ +package ru.tinkoff.edu.java.bot.configuration.records; + +public record Bot(String token, String name) { +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Scheduler.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Scheduler.java new file mode 100644 index 0000000..daed115 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/configuration/records/Scheduler.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.bot.configuration.records; + +import java.time.Duration; + +public record Scheduler(Duration interval) {} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/BotMain.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/BotMain.java new file mode 100644 index 0000000..13d6b65 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/BotMain.java @@ -0,0 +1,33 @@ +package ru.tinkoff.edu.java.bot.handler; + +import com.pengrad.telegrambot.TelegramBot; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.bot.configuration.records.ApplicationConfig; + + +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableConfigurationProperties(ApplicationConfig.class) +public class BotMain { + + String token; + static TelegramBot bot; + private JdbcTemplate jdbcTemplate; + + public BotMain(String token, JdbcTemplate jdbcTemplate) { + this.token = token; + this.jdbcTemplate = jdbcTemplate; + } + + public void start() { + bot = new TelegramBot(token); + bot.setUpdatesListener(new Updater(bot, jdbcTemplate)); + } + + public void end() { + bot.removeGetUpdatesListener(); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java new file mode 100644 index 0000000..6b57338 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java @@ -0,0 +1,42 @@ +package ru.tinkoff.edu.java.bot.handler; + +import java.util.ArrayList; + +public class DB { + + static ArrayList list = new ArrayList(); + + public static void addLink(String link) { + list.add(link); + } + + public static void rmLink(String link) { + list.remove(link); + } + + public static String getListParse() { + + int i = 1; + + String out_list = ""; + + for(String element: list){ + + out_list += element; + + if(i != list.size()) { + out_list += ", "; + } + i++; + } + return out_list; + } + + public static boolean listIsEmpty() { + return list.isEmpty(); + } + + public static boolean linkContain(String link) { + return list.contains(link); + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/MessageHandler.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/MessageHandler.java new file mode 100644 index 0000000..87f2ab0 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/MessageHandler.java @@ -0,0 +1,39 @@ +package ru.tinkoff.edu.java.bot.handler; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.bot.handler.commands.All; + +public class MessageHandler extends All { + + private final JdbcTemplate jdbcTemplate; + private final long chatid; + + public MessageHandler(JdbcTemplate jdbcTemplate, long chatid) { + this.jdbcTemplate = jdbcTemplate; + this.chatid = chatid; + } + + public boolean is_command(String message) { + return message.startsWith("/"); + } + + public String call_command(String command, String arg) { + return switch (command) { + case "/start" -> start(jdbcTemplate, chatid); + case "/help" -> help(); + case "/track" -> track(jdbcTemplate, arg, chatid); + case "/list" -> list(jdbcTemplate, chatid); + case "/untrack" -> untrack(jdbcTemplate, arg, chatid); + default -> unknow(); + }; + } + + public String call_command(String command) { + return switch (command) { + case "/start" -> start(jdbcTemplate, chatid); + case "/help" -> help(); + case "/list" -> list(jdbcTemplate, chatid); + default -> unknow(); + }; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/Updater.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/Updater.java new file mode 100644 index 0000000..7965170 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/Updater.java @@ -0,0 +1,44 @@ +package ru.tinkoff.edu.java.bot.handler; + +import com.pengrad.telegrambot.TelegramBot; +import com.pengrad.telegrambot.UpdatesListener; +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.model.request.*; +import com.pengrad.telegrambot.request.SendMessage; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.util.List; + +public class Updater implements UpdatesListener { + + MessageHandler handler; + String command; + TelegramBot bot; + private JdbcTemplate jdbcTemplate; + private long chatid; + + public Updater(TelegramBot bot, JdbcTemplate jdbcTemplate) { + this.bot = bot; + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public int process(List updates) { + Update update = updates.get(0); + handler = new MessageHandler(jdbcTemplate, update.message().chat().id()); + if(handler.is_command(update.message().text())) { + String[] parse = update.message().text().split(" "); + if(parse.length > 1) command = handler.call_command(parse[0], parse[1]); + else command = handler.call_command(parse[0]); + bot.execute( + new SendMessage(update.message().chat().id(), command) + .replyMarkup(new ReplyKeyboardMarkup(new String[][]{ + {"/start", "/help"}, + {"/track testlink", "/untrack testlink", "/list"} + }).resizeKeyboard(true) + ).parseMode(ParseMode.HTML) + ); + } + return UpdatesListener.CONFIRMED_UPDATES_ALL; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/All.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/All.java new file mode 100644 index 0000000..5f63723 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/All.java @@ -0,0 +1,7 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +public class All implements List, Start, Track, Untrack, Help { + protected String unknow() { + return "НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°"; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Help.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Help.java new file mode 100644 index 0000000..4d0da5a --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Help.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +public interface Help { + default String help() { + return "/start -- Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ\n" + + "/help -- вывСсти ΠΎΠΊΠ½ΠΎ с ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ\n" + + "/track [link] -- Π½Π°Ρ‡Π°Ρ‚ΡŒ отслСТиваниС ссылки\n" + + "/untrack [link] -- ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ отслСТиваниС ссылки\n" + + "/list -- ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ список отслСТиваСмых ссылок"; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java new file mode 100644 index 0000000..280f80a --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java @@ -0,0 +1,37 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +import com.google.gson.JsonObject; +import okhttp3.Interceptor; +import org.springframework.jdbc.BadSqlGrammarException; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.bot.handler.DB; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.UnauthorizationException; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; + +import java.util.ArrayList; + +public interface List extends LinkOperations, ChatOperations, LinkChatOperations { + + default String list(JdbcTemplate jdbc, long chat) { + int i; + String links = ""; + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + return "ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"; + } + ArrayList link_list = new ArrayList<>(); + try { + for (i = 0; i < i_get_all_links_for_chat(jdbc, chat_id).size(); i++) { + link_list.add(i_get_all_links_for_chat(jdbc, chat_id).get(i).linkid()); + } + for (i = 0; i < i_findAllLink(jdbc, link_list).size(); i++) { + links += i_findAllLink(jdbc, link_list).get(i).url() + "\n"; + } + return links; + } catch (BadSqlGrammarException e) { + return "Π£ вас Π½Π΅Ρ‚ ссылок"; + } + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java new file mode 100644 index 0000000..d2d5459 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java @@ -0,0 +1,19 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryExsistException; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; + +public interface Start extends ChatOperations { + + default String start(JdbcTemplate jdbc, long chat) { + int chat_id = i_findChat(jdbc, chat); + if (chat_id != 0) { + return "Π’Ρ‹ ΡƒΠΆΠ΅ зарСгистрированы"; + } else { + i_addChat(jdbc, chat); + return "РСгистрация ΡƒΡΠΏΠ΅ΡˆΠ½Π°, ваш tg_id = " + chat; + } + } +} + diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java new file mode 100644 index 0000000..9080b48 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java @@ -0,0 +1,47 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import ru.tinkoff.edu.java.bot.handler.DB; +import ru.tinkoff.edu.java.linkparser.LinkParser; +import ru.tinkoff.edu.java.scrapper.client.ClientConfiguration; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryExsistException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryNotExsistException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.NullLinkException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.UnauthorizationException; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; +import ru.tinkoff.edu.java.scrapper.model.RemoveLinkRequest; + +public interface Track extends LinkOperations, LinkChatOperations, ChatOperations { + default String track(JdbcTemplate jdbc, String link, long chat) { + ClientConfiguration client = new ClientConfiguration(); + LinkParser parser = new LinkParser(); + if (parser.getLink(link) == null) { + return "Бсылка Π½Π΅Π²Π°Π»ΠΈΠ΄Π½Π°"; + } + try { + client.gitHubClient(parser.getLink(link)); + } catch (WebClientResponseException e) { + try { + client.stackOverflowClient(parser.getLink(link)); + } catch (WebClientResponseException ex) { + return "Бсылка Π½Π΅ поддСрТиваСтся, доступны: Git, StackOverFlow"; + } + } + int link_id = i_findLink(jdbc, link); + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + return "ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"; + } + if (link_id == 0) { + i_addLink(jdbc, link); + link_id = i_findLink(jdbc, link); + } + if (i_findLinkChat(jdbc, link_id, chat_id)) { + addLinkChat(jdbc, link_id, chat_id); + return "Бсылка ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°!"; + }else return"Бсылка ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°!"; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java new file mode 100644 index 0000000..6615feb --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java @@ -0,0 +1,24 @@ +package ru.tinkoff.edu.java.bot.handler.commands; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.bot.handler.DB; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; + +public interface Untrack extends LinkOperations, LinkChatOperations, ChatOperations { + default String untrack(JdbcTemplate jdbc, String link, long chat) { + int link_id = i_findLink(jdbc, link); + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + return "ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"; + } + if (link_id != 0) { + i_removeLink(jdbc, link); + if (!i_findLinkChat(jdbc, link_id, chat_id)) { + i_removeLinkChat(jdbc, link_id, chat_id); + } + return "Бсылка ΡƒΠ΄Π°Π»Π΅Π½Π°"; + } else return "Бсылки Π½Π΅ сущСствуСт"; + } +} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/ApiErrorResponse.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/ApiErrorResponse.java new file mode 100644 index 0000000..57e1c06 --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/ApiErrorResponse.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.bot.model; + +import java.util.List; + +public record ApiErrorResponse( + String description, + String code, + String exceptionName, + String exceptionMessage, + List stacktrace +) {} \ No newline at end of file diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/LinkUpdate.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/LinkUpdate.java new file mode 100644 index 0000000..d6b250b --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/model/LinkUpdate.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.bot.model; + +import java.util.List; + +public record LinkUpdate(String url) { +} \ No newline at end of file diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/schedule/LinkUpdaterScheduler.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/schedule/LinkUpdaterScheduler.java new file mode 100644 index 0000000..1b2ff0f --- /dev/null +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/schedule/LinkUpdaterScheduler.java @@ -0,0 +1,17 @@ +package ru.tinkoff.edu.java.bot.schedule; + +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.logging.Level; +import java.util.logging.Logger; + +@Service +public class LinkUpdaterScheduler { + private final static Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); + + @Scheduled(fixedDelayString = "${app.scheduler.interval}") + public void update() { + LOGGER.log(Level.INFO, "Info bot called"); + } +} diff --git a/FP/bot/src/main/resources/application.properties b/FP/bot/src/main/resources/application.properties new file mode 100644 index 0000000..6600aaa --- /dev/null +++ b/FP/bot/src/main/resources/application.properties @@ -0,0 +1,9 @@ +app.test=123 +springdoc.swagger-ui.path=/swagger-ui +app.scheduler.interval=50000 +app.bot.token=5805337447:AAGnmh2isW2115L7tJWFojbpmSjNrarTvxQ +app.bot.name=@SFRETbot +server.port=8081 +app.exchange=my-direct-exchange +app.queue=my-queue +app.routingKey=my-routing-key \ No newline at end of file diff --git a/FP/docker-compose.yml b/FP/docker-compose.yml new file mode 100644 index 0000000..4195e6e --- /dev/null +++ b/FP/docker-compose.yml @@ -0,0 +1,54 @@ +version: '1.-' + +services: + postgres: + container_name: postgres + image: postgres:15.2 + environment: + POSTGRES_DB: postgres + POSTGRES_USER: scrap_user + POSTGRES_PASSWORD: hard_password + volumes: + - ./migrations/postgres_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - backend + + liquibase-migrations: + container_name: liquibase + image: liquibase/liquibase:4.18 + deploy: + restart_policy: + condition: on-failure + delay: 10s + max_attempts: 10 + command: + - --hub-mode=off + - --changelog-file=master.xml + - --driver=org.postgresql.Driver + - --url=jdbc:postgresql://postgres:5432/postgres + - --username=scrap_user + - --password=hard_password + - --logLevel=debug + - update + volumes: + - ./migrations:/liquibase/changelog + networks: + - backend + + rabbitmq: + image: rabbitmq:3-management-alpine + container_name: rabbitmq + ports: + - 5672:5672 # ΠŸΠΎΡ€Ρ‚ для AMQP + - 15672:15672 # ΠŸΠΎΡ€Ρ‚ для RabbitMQ Management UI + volumes: + - ./rabbitmq:/var/lib/rabbitmq + environment: + - RABBITMQ_DEFAULT_USER=guest + - RABBITMQ_DEFAULT_PASS=guest + +networks: + backend: + driver: bridge \ No newline at end of file diff --git a/FP/link-parser/pom.xml b/FP/link-parser/pom.xml new file mode 100644 index 0000000..088df38 --- /dev/null +++ b/FP/link-parser/pom.xml @@ -0,0 +1,26 @@ + + + + org.example + FP + 1.0 + + + 4.0.0 + + link-parser + + + org.junit.jupiter + junit-jupiter + test + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + \ No newline at end of file diff --git a/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/LinkParser.java b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/LinkParser.java new file mode 100644 index 0000000..1f217ea --- /dev/null +++ b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/LinkParser.java @@ -0,0 +1,18 @@ +package ru.tinkoff.edu.java.linkparser; + +import ru.tinkoff.edu.java.linkparser.absracts.*; + +public class LinkParser { + + public String getLink(String link) { + + AbstractParser gitParser = new GitParser(); + AbstractParser stackParser = new StackParser(); + AbstractParser otherParser = new OtherParser(); + + gitParser.setNextParser(stackParser); + stackParser.setNextParser(otherParser); + + return gitParser.logParser(link); + } +} diff --git a/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/AbstractParser.java b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/AbstractParser.java new file mode 100644 index 0000000..503e413 --- /dev/null +++ b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/AbstractParser.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.linkparser.absracts; + +public abstract class AbstractParser { + + private AbstractParser nextParser; + + public void setNextParser(AbstractParser nextParser) { + this.nextParser = nextParser; + } + + public String logParser (String link) { + if(nextParser != null) { + if(this.parsAbstract(link) == null) return nextParser.logParser(link); + } + return this.parsAbstract(link); + } + + abstract protected String parsAbstract(String link); + +} diff --git a/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/GitParser.java b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/GitParser.java new file mode 100644 index 0000000..9525306 --- /dev/null +++ b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/GitParser.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.linkparser.absracts; + +import java.util.Objects; + +public class GitParser extends AbstractParser { + + @Override + protected String parsAbstract(String link) { + + String[] parsed = link.split("/"); + + if (parsed.length < 2) return null; + + if (!Objects.equals(parsed[2], "github.com")) return null; + + if (parsed.length > 4) return parsed[3] + "/" + parsed[4]; + + return null; + } +} diff --git a/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/OtherParser.java b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/OtherParser.java new file mode 100644 index 0000000..f3746fe --- /dev/null +++ b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/OtherParser.java @@ -0,0 +1,9 @@ +package ru.tinkoff.edu.java.linkparser.absracts; + +public class OtherParser extends AbstractParser { + + @Override + protected String parsAbstract(String link) { + return null; + } +} diff --git a/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/StackParser.java b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/StackParser.java new file mode 100644 index 0000000..571ea58 --- /dev/null +++ b/FP/link-parser/src/main/java/ru/tinkoff/edu/java/linkparser/absracts/StackParser.java @@ -0,0 +1,19 @@ +package ru.tinkoff.edu.java.linkparser.absracts; + +import java.util.Objects; + +public class StackParser extends AbstractParser { + + @Override + protected String parsAbstract(String link) { + + String[] parsed = link.split("/"); + + if (parsed.length < 5) return null; + if (!Objects.equals(parsed[2], "stackoverflow.com")) return null; + if (!Objects.equals(parsed[3], "questions")) return null; + + + return parsed[4]; + } +} diff --git a/FP/link-parser/src/test/java/LinkParserTest.java b/FP/link-parser/src/test/java/LinkParserTest.java new file mode 100644 index 0000000..7bd8349 --- /dev/null +++ b/FP/link-parser/src/test/java/LinkParserTest.java @@ -0,0 +1,24 @@ +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import ru.tinkoff.edu.java.linkparser.LinkParser; + +public class LinkParserTest { + + String gitLink = "https://github.com/Ray-Not/JavaGuava"; + String invalidLink = "https://gitrub.com/"; + String invalidLink2 = "https://github.com/Ray-Not"; + String expectGitLink = "Ray-Not/JavaGuava"; + String stackLink = "https://stackoverflow.com/questions/1642028/what-is-the-operator-in-c"; + String expectStackLink = "1642028"; + + LinkParser pars = new LinkParser(); + + @Test + public void validGitPars(){ + Assertions.assertNull(pars.getLink(invalidLink)); + Assertions.assertNull(pars.getLink(invalidLink2)); + Assertions.assertNotNull(pars.getLink(gitLink)); + Assertions.assertEquals(pars.getLink(gitLink), expectGitLink); + Assertions.assertEquals(pars.getLink(stackLink), expectStackLink); + } +} diff --git a/FP/migrations/chats_links_scheme.sql b/FP/migrations/chats_links_scheme.sql new file mode 100644 index 0000000..63882e8 --- /dev/null +++ b/FP/migrations/chats_links_scheme.sql @@ -0,0 +1,8 @@ +CREATE TABLE links (id INTEGER, link VARCHAR(128) NOT NULL); + +CREATE TABLE tgChats (id INTEGER, tg_chat_id BIGINT NOT NULL); + +CREATE TABLE links_tgChats ( + linkid INTEGER, + chatid INTEGER +); \ No newline at end of file diff --git a/FP/FP/migrations/master.xml b/FP/migrations/master.xml similarity index 83% rename from FP/FP/migrations/master.xml rename to FP/migrations/master.xml index c566afc..5d643de 100644 --- a/FP/FP/migrations/master.xml +++ b/FP/migrations/master.xml @@ -7,7 +7,5 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> - - - + \ No newline at end of file diff --git a/FP/FP/pom.xml b/FP/pom.xml similarity index 65% rename from FP/FP/pom.xml rename to FP/pom.xml index a1baa3d..e38a124 100644 --- a/FP/FP/pom.xml +++ b/FP/pom.xml @@ -1,85 +1,54 @@ - - 4.0.0 - project - project - 0.0.1-SNAPSHOT - pom - - bot - link-parser - scrapper - scrapper-jooq - - - 3.0.1 - 2022.0.0 - 3.10.1 - 23.1.0 - UTF-8 - + + + 4.0.0 - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - + org.example - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - org.junit.jupiter - junit-jupiter-params - ${junit.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - org.springframework.boot - spring-boot-starter-test - ${spring.test.version} - test - - - + FP + + pom + 1.0 - - - org.jetbrains - annotations - ${annotations.version} - provided - - + + bot + link-parser + scrapper + + + + UTF-8 + 17 + 17 + 3.8.1 + 3.0.1 + 2022.0.0 + 23.1.0 + 5.8.1 + 1.18.0 + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + false + + org.springframework.boot spring-boot-maven-plugin - ${spring-boot.version} + ${spring-boot.version true @@ -108,16 +77,40 @@ 17 true - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + org.jetbrains + annotations + ${annotations.version} + provided + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + \ No newline at end of file diff --git a/FP/FP/scrapper/pom.xml b/FP/scrapper/pom.xml similarity index 69% rename from FP/FP/scrapper/pom.xml rename to FP/scrapper/pom.xml index 1b0c4fa..fad5590 100644 --- a/FP/FP/scrapper/pom.xml +++ b/FP/scrapper/pom.xml @@ -2,27 +2,38 @@ - 4.0.0 - project - project - 0.0.1-SNAPSHOT - + org.example + FP + 1.0 + + + 4.0.0 + + scrapper - scrapper + + 3.0.1 + 2.7.6 + + - org.springframework.boot - spring-boot-starter-web + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.0.2 + org.springframework.boot spring-boot-starter-validation + ${starter-validation.version} org.springframework.boot - spring-boot-starter-webflux + spring-boot-starter-web + ${starter-web.version} org.springframework.boot @@ -45,25 +56,26 @@ lombok true + - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.0.2 + org.example + link-parser + 1.0 + compile + + - ru.tinkoff.edu - link-parser - 1.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-webflux + 3.0.5 + org.testcontainers junit-jupiter test - - org.springframework.boot - spring-boot-starter-test - org.testcontainers postgresql @@ -74,6 +86,7 @@ liquibase-core test + org.springframework.boot spring-boot-starter-jdbc @@ -84,37 +97,20 @@ runtime - org.jooq - jooq + org.junit.jupiter + junit-jupiter + test - - org.springframework.boot - spring-boot-starter-data-jpa + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + org.springframework.boot spring-boot-starter-amqp + 3.0.6 - - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java new file mode 100644 index 0000000..0539e02 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java @@ -0,0 +1,29 @@ +package ru.tinkoff.edu.java.scrapper; + +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; +import ru.tinkoff.edu.java.scrapper.rabbitmq.ScrapperQueueProducer; +import ru.tinkoff.edu.java.scrapper.rabbitmq.SendNoticeServiceQueue; + +@SpringBootApplication +@EnableConfigurationProperties(ApplicationConfig.class) +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +public class ScrapperApplication { + + public static void main(String[] args) { + var ctx = SpringApplication.run(ScrapperApplication.class, args); + ApplicationConfig config = ctx.getBean(ApplicationConfig.class); + System.out.println("----------------------------------------------------------------"); +// SendNoticeServiceQueue notificationService = new SendNoticeServiceQueue(new ScrapperQueueProducer( +// new RabbitTemplate(), +// config +// )); +// notificationService.sendNotice("Π’ΠΎΡ‚-Π²ΠΎΡ‚"); +// Cannot invoke "org.springframework.amqp.rabbit.connection.ConnectionFactory.createConnection()" because "connectionFactory" is null + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerLinks.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerLinks.java new file mode 100644 index 0000000..47540df --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerLinks.java @@ -0,0 +1,46 @@ +package ru.tinkoff.edu.java.scrapper.api; + +import org.springframework.http.HttpStatus; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.tinkoff.edu.java.scrapper.jdbc.JdbcLinkService; +import ru.tinkoff.edu.java.scrapper.model.AddLinkRequest; +import ru.tinkoff.edu.java.scrapper.model.LinkResponse; +import ru.tinkoff.edu.java.scrapper.model.RemoveLinkRequest; + +import java.util.List; + +@RequestMapping("/links") +@RestController +public class ScrapperControllerLinks { + private final JdbcTemplate jdbcTemplate; + JdbcLinkService linkService = new JdbcLinkService(); + + public ScrapperControllerLinks(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping + public void linksDelete( + @RequestHeader("Tg-Chat-Id") Long tgChatId, + @RequestBody RemoveLinkRequest removeLinkRequest + ) { + linkService.removeLink(jdbcTemplate, removeLinkRequest, tgChatId); + } + + @GetMapping + public List linksGet(@RequestHeader("Tg-Chat-Id") Long tgChatId) { + return linkService.getLinks(jdbcTemplate, tgChatId); + } + + @PostMapping + public void linksPost( + @RequestHeader("Tg-Chat-Id") Long tgChatId, + @RequestBody AddLinkRequest addLinkRequest + ) { + linkService.addLink(jdbcTemplate, addLinkRequest, tgChatId); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerTg.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerTg.java new file mode 100644 index 0000000..cc96bfb --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/api/ScrapperControllerTg.java @@ -0,0 +1,29 @@ +package ru.tinkoff.edu.java.scrapper.api; + +import org.springframework.http.HttpStatus; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.bind.annotation.*; +import ru.tinkoff.edu.java.scrapper.jdbc.JdbcChatService; +import ru.tinkoff.edu.java.scrapper.jdbc.JdbcLinkService; + +@RequestMapping("/tg-chat") +@RestController +public class ScrapperControllerTg { + + private final JdbcTemplate jdbcTemplate; + JdbcChatService chatService = new JdbcChatService(); + public ScrapperControllerTg(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping("/{id}") + public void tgChatIdDelete(@PathVariable Long id) { + chatService.removeChat(jdbcTemplate, id); + } + + @PostMapping("/{id}") + public void tgChatIdPost(@PathVariable long id) { + chatService.addChat(jdbcTemplate, id); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/ClientConfiguration.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/ClientConfiguration.java new file mode 100644 index 0000000..ee3e6b1 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/ClientConfiguration.java @@ -0,0 +1,57 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.client.WebClient; +import ru.tinkoff.edu.java.linkparser.LinkParser; + +import java.util.Objects; + + +@Configuration +public class ClientConfiguration { + + private final String BASE_GIT_URL = "https://github.com/Ray-Not/JavaGuava"; + private final String BASE_STACK_URL = "https://stackoverflow.com/questions/1642028/what-is-the-operator-in-c"; + @Value("${git.link}") + String gitLink; + @Value("${stack.link}") + String stackLink; + static WebClient.Builder builder = WebClient.builder(); + LinkParser pars = new LinkParser(); + + @Bean + public WeatherRecord weatherClient() { + WeatherRecord weatherResponse = builder.build() + .get() + .uri("http://api.weatherapi.com/v1/current.json?key=3ff5d13401e44f30a14170938230204&q=Russia&aqi=no") + .retrieve() + .bodyToMono(WeatherRecord.class) + .block(); + return weatherResponse; + } + + public GitHubRecord gitHubClient( + String link + ) { + return builder.build() + .get() + .uri("https://api.github.com/repos/" + link) + .retrieve() + .bodyToMono(GitHubRecord.class) + .block(); + } + + public StackOverflowRecord stackOverflowClient( + String link + ) { + String params = "?order=desc&sort=activity&site=stackoverflow"; + return builder.build() + .get() + .uri("https://api.stackexchange.com/2.3/questions/" + link + params) + .retrieve() + .bodyToMono(StackOverflowRecord.class) + .block(); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubRecord.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubRecord.java new file mode 100644 index 0000000..97ef980 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/GitHubRecord.java @@ -0,0 +1,19 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.OffsetDateTime; +import java.util.HashMap; + +public record GitHubRecord( + @JsonProperty("full_name") String name, + @JsonProperty("owner") HashMap owner, + @JsonProperty("private") boolean is_private, + @JsonProperty("node_id") String node_id, + @JsonProperty("html_url") String url, + @JsonProperty("description") String description, + @JsonProperty("created_at") OffsetDateTime createdAt, + @JsonProperty("updated_at") OffsetDateTime updatedAt, + @JsonProperty("pushed_at") OffsetDateTime pushedAt + +) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowRecord.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowRecord.java new file mode 100644 index 0000000..6013400 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/StackOverflowRecord.java @@ -0,0 +1,10 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public record StackOverflowRecord( + @JsonProperty("has_more") boolean has_more, + @JsonProperty("items") List owner +) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/WeatherRecord.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/WeatherRecord.java new file mode 100644 index 0000000..5ee9adc --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/client/WeatherRecord.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.client; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.HashMap; +import java.util.List; + +public record WeatherRecord( + @JsonProperty("location") HashMap location, + @JsonProperty("current") HashMap current + ) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java new file mode 100644 index 0000000..52af096 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/ApplicationConfig.java @@ -0,0 +1,37 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import jakarta.validation.constraints.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.validation.annotation.Validated; +import ru.tinkoff.edu.java.scrapper.rabbitmq.ScrapperQueueProducer; +import ru.tinkoff.edu.java.scrapper.rabbitmq.SendNoticeServiceHttp; +import ru.tinkoff.edu.java.scrapper.rabbitmq.SendNoticeServiceImplement; +import ru.tinkoff.edu.java.scrapper.rabbitmq.SendNoticeServiceQueue; +import ru.tinkoff.edu.java.scrapper.schedule.Scheduler; + +@Validated +@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false) +@EnableScheduling +public record ApplicationConfig( + @NotNull String test, + @NotNull Scheduler scheduler, + Boolean useQueue, + String exchange, + String routingKey, + String queue +) { +@Bean +public SendNoticeServiceImplement notificationService(ScrapperQueueProducer queueProducer/*, BotClient botClient */) { + if (useQueue) { + return new SendNoticeServiceQueue(queueProducer); + } else { + /* Π—Π°Π³Π»ΡƒΡˆΠΊΠ° */ + return new SendNoticeServiceHttp(); + } +} +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java new file mode 100644 index 0000000..8682387 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/configuration/RabbitMQConfiguration.java @@ -0,0 +1,71 @@ +package ru.tinkoff.edu.java.scrapper.configuration; + +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; +import org.springframework.amqp.core.*; +import org.springframework.amqp.support.converter.ClassMapper; +import org.springframework.amqp.support.converter.DefaultClassMapper; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.tinkoff.edu.java.scrapper.model.LinkUpdate; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class RabbitMQConfiguration { + + private final ApplicationConfig config; + + public RabbitMQConfiguration(ApplicationConfig config) { + this.config = config; + } + + @Bean + public DirectExchange exchange() { + return new DirectExchange(config.exchange()); + } + + @Bean + public Queue queue() { + return QueueBuilder.durable(config.queue()) + .withArgument("x-dead-letter-exchange", config.queue() + ".dlq") + .build(); + } + + @Bean + public Binding binding(Queue queue, DirectExchange exchange) { + return BindingBuilder.bind(queue).to(exchange).with(config.routingKey()); + } + + @Bean + public ClassMapper classMapper(){ + Map> mappings = new HashMap<>(); + mappings.put("ru.tinkoff.edu.java.scrapper.model.LinkUpdate", LinkUpdate.class); + + DefaultClassMapper classMapper = new DefaultClassMapper(); + classMapper.setTrustedPackages("ru.tinkoff.edu.java.scrapper.model.*"); + classMapper.setIdClassMapping(mappings); + return classMapper; + } + + @Bean + public MessageConverter jsonMessageConverter(ClassMapper classMapper){ + Jackson2JsonMessageConverter jsonConverter=new Jackson2JsonMessageConverter(); + jsonConverter.setClassMapper(classMapper); + return jsonConverter; + } + + @Bean + public ConnectionFactory connectionFactory() { + CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost", 5672); + connectionFactory.setUsername("guest"); + connectionFactory.setPassword("guest"); + // Π”Ρ€ΡƒΠ³ΠΈΠ΅ настройки, Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ + + return connectionFactory; + } +} \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/ScrapperExceptionHandler.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/ScrapperExceptionHandler.java new file mode 100644 index 0000000..55fc0c9 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/ScrapperExceptionHandler.java @@ -0,0 +1,78 @@ +package ru.tinkoff.edu.java.scrapper.exceptions; + +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MissingRequestHeaderException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryExsistException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryNotExsistException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.NullLinkException; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.UnauthorizationException; +import ru.tinkoff.edu.java.scrapper.exceptions.model.ApiErrorResponse; + +@RestControllerAdvice +public class ScrapperExceptionHandler { + + private ApiErrorResponse setException(Exception exception) { + String[] parsing_class = exception.getClass().toString().split("\\."); + String class_name = parsing_class[parsing_class.length - 1]; + ApiErrorResponse errorObj = new ApiErrorResponse( + exception.getMessage(), + class_name, + exception.toString() + ); + return errorObj; + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ApiErrorResponse MessageNotReadable(HttpMessageNotReadableException e) { + return setException(e); + } + + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ApiErrorResponse MethodNotSupported(HttpRequestMethodNotSupportedException e) { + return setException(e); + } + + @ExceptionHandler(MissingRequestHeaderException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ApiErrorResponse MissingRequestHeader(MissingRequestHeaderException e) { + return setException(e); + } + + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ApiErrorResponse ArgumentTypeMismatch(MethodArgumentTypeMismatchException e) { + return setException(e); + } + + @ExceptionHandler(NullLinkException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ApiErrorResponse NullLink(NullLinkException e) { + return setException(e); + } + + @ExceptionHandler(UnauthorizationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public ApiErrorResponse Unauthorization(UnauthorizationException e) { + return setException(e); + } + + @ExceptionHandler(EntryExsistException.class) + @ResponseStatus(HttpStatus.FOUND) + public ApiErrorResponse EntryExsist(EntryExsistException e) { + return setException(e); + } + + @ExceptionHandler(EntryNotExsistException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ApiErrorResponse EntryNotExsist(EntryNotExsistException e) { + return setException(e); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryExsistException.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryExsistException.java new file mode 100644 index 0000000..fca436d --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryExsistException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.customExceptions; + +public class EntryExsistException extends RuntimeException { + + public EntryExsistException() { + super(); + } + + public EntryExsistException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryNotExsistException.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryNotExsistException.java new file mode 100644 index 0000000..e25ba25 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/EntryNotExsistException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.customExceptions; + +public class EntryNotExsistException extends RuntimeException { + + public EntryNotExsistException() { + super(); + } + + public EntryNotExsistException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullDBException.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullDBException.java new file mode 100644 index 0000000..cd7baa2 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullDBException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.customExceptions; + +public class NullDBException extends RuntimeException { + + public NullDBException() { + super(); + } + + public NullDBException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullLinkException.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullLinkException.java new file mode 100644 index 0000000..00ddf4e --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/NullLinkException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.customExceptions; + +public class NullLinkException extends RuntimeException { + + public NullLinkException() { + super(); + } + + public NullLinkException(String s) { + super(s); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/UnauthorizationException.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/UnauthorizationException.java new file mode 100644 index 0000000..2135ddc --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/customExceptions/UnauthorizationException.java @@ -0,0 +1,12 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.customExceptions; + +public class UnauthorizationException extends RuntimeException { + + public UnauthorizationException() { + super(); + } + + public UnauthorizationException(String s) { + super(s); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/model/ApiErrorResponse.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/model/ApiErrorResponse.java new file mode 100644 index 0000000..0a8994e --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/exceptions/model/ApiErrorResponse.java @@ -0,0 +1,7 @@ +package ru.tinkoff.edu.java.scrapper.exceptions.model; + +public record ApiErrorResponse( + String exceptionMessage, + String description, + String exceptionName +) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcChatService.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcChatService.java new file mode 100644 index 0000000..c8757c8 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcChatService.java @@ -0,0 +1,26 @@ +package ru.tinkoff.edu.java.scrapper.jdbc; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.*; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; + +public class JdbcChatService implements LinkOperations, ChatOperations, LinkChatOperations { + public void addChat(JdbcTemplate jdbc, long chat) { + int chat_id = i_findChat(jdbc, chat); + if (chat_id != 0) { + throw new EntryExsistException("Π’Ρ‹ ΡƒΠΆΠ΅ зарСгистрированы"); + } else { + i_addChat(jdbc, chat); + } + } + + public void removeChat(JdbcTemplate jdbc, long chat) { + int chat_id = i_findChat(jdbc, chat); + if (chat_id != 0) { + i_removeChat(jdbc, chat); + i_removeLinkChatAllChat(jdbc, chat_id); + } else throw new EntryNotExsistException("ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½"); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcLinkService.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcLinkService.java new file mode 100644 index 0000000..2d62856 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/JdbcLinkService.java @@ -0,0 +1,81 @@ +package ru.tinkoff.edu.java.scrapper.jdbc; + +import org.springframework.jdbc.BadSqlGrammarException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import ru.tinkoff.edu.java.linkparser.LinkParser; +import ru.tinkoff.edu.java.scrapper.model.AddLinkRequest; +import ru.tinkoff.edu.java.scrapper.model.LinkResponse; +import ru.tinkoff.edu.java.scrapper.model.RemoveLinkRequest; +import ru.tinkoff.edu.java.scrapper.client.ClientConfiguration; +import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.*; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; + +import java.util.ArrayList; +import java.util.List; + +public class JdbcLinkService implements LinkOperations, ChatOperations, LinkChatOperations { + public void addLink(JdbcTemplate jdbc, AddLinkRequest link, Long chat) { + ClientConfiguration client = new ClientConfiguration(); + LinkParser parser = new LinkParser(); + if (parser.getLink(link.link()) == null) { + throw new NullLinkException("Бсылка Π½Π΅Π²Π°Π»ΠΈΠ΄Π½Π°"); + } + try { + client.gitHubClient(parser.getLink(link.link())); + } catch (WebClientResponseException e) { + try { + client.stackOverflowClient(parser.getLink(link.link())); + } catch (WebClientResponseException ex) { + throw new NullLinkException("Бсылка Π½Π΅ поддСрТиваСтся, доступны: Git, StackOverFlow"); + } + } + int link_id = i_findLink(jdbc, link.link()); + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + throw new UnauthorizationException("ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"); + } + if (link_id == 0) { + i_addLink(jdbc, link.link()); + link_id = i_findLink(jdbc, link.link()); + } + if (i_findLinkChat(jdbc, link_id, chat_id)) { + addLinkChat(jdbc, link_id, chat_id); + }else throw new EntryExsistException("Бсылка ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°!"); + } + + public void removeLink(JdbcTemplate jdbc, RemoveLinkRequest link, long chat) { + int link_id = i_findLink(jdbc, link.link()); + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + throw new UnauthorizationException("ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"); + } + if (link_id != 0) { + i_removeLink(jdbc, link.link()); + } else throw new EntryNotExsistException("Бсылки Π½Π΅ сущСствуСт"); + if (!i_findLinkChat(jdbc, link_id, chat_id)) { + i_removeLinkChat(jdbc, link_id, chat_id); + } + } + + public List getLinks(JdbcTemplate jdbc, long chat) { + int i; + int chat_id = i_findChat(jdbc, chat); + if (chat_id == 0) { + throw new UnauthorizationException("ΠŸΠ΅Ρ€Π΅Π΄ использованиСм Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ"); + } + ArrayList link_list = new ArrayList<>(); + try { + for (i = 0; i < i_get_all_links_for_chat(jdbc, chat_id).size(); i++) { + link_list.add(i_get_all_links_for_chat(jdbc, chat_id).get(i).linkid()); + } + return i_findAllLink(jdbc, link_list); + } catch (BadSqlGrammarException e) { + throw new EntryNotExsistException("Π£ вас Π½Π΅Ρ‚ ссылок"); + } + + } + +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/config/jdbcBean.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/config/jdbcBean.java new file mode 100644 index 0000000..74a1fbe --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/config/jdbcBean.java @@ -0,0 +1,25 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import javax.sql.DataSource; +@Configuration +public class jdbcBean { + @Bean + public DataSource dataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("org.postgresql.Driver"); + dataSource.setUrl("jdbc:postgresql://localhost:5432/postgres"); + dataSource.setUsername("scrap_user"); + dataSource.setPassword("hard_password"); + + return dataSource; + } + @Bean + public JdbcTemplate jdbcTemplate () { + return new JdbcTemplate (dataSource()); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/ChatMapper.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/ChatMapper.java new file mode 100644 index 0000000..026139a --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/ChatMapper.java @@ -0,0 +1,14 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.mappers; + +import org.springframework.jdbc.core.RowMapper; +import ru.tinkoff.edu.java.scrapper.model.ChatResponse; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ChatMapper implements RowMapper { + @Override + public ChatResponse mapRow(ResultSet rs, int rowNum) throws SQLException { + return new ChatResponse(rs.getLong("tg_chat_id"), rs.getInt("id")); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkChatMapper.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkChatMapper.java new file mode 100644 index 0000000..4b52ef9 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkChatMapper.java @@ -0,0 +1,14 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.mappers; + +import org.springframework.jdbc.core.RowMapper; +import ru.tinkoff.edu.java.scrapper.model.LinkChatResponse; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class LinkChatMapper implements RowMapper { + @Override + public LinkChatResponse mapRow(ResultSet rs, int rowNum) throws SQLException { + return new LinkChatResponse(rs.getInt("linkid"), rs.getInt("chatid")); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkMapper.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkMapper.java new file mode 100644 index 0000000..914d113 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/mappers/LinkMapper.java @@ -0,0 +1,15 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.mappers; + + +import org.springframework.jdbc.core.RowMapper; +import ru.tinkoff.edu.java.scrapper.model.LinkResponse; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class LinkMapper implements RowMapper { + @Override + public LinkResponse mapRow(ResultSet rs, int rowNum) throws SQLException { + return new LinkResponse(rs.getString("link"), rs.getInt("id")); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/ChatOperations.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/ChatOperations.java new file mode 100644 index 0000000..3c36c88 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/ChatOperations.java @@ -0,0 +1,50 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.operations; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.scrapper.jdbc.mappers.ChatMapper; +import ru.tinkoff.edu.java.scrapper.jdbc.mappers.LinkMapper; + +public interface ChatOperations { + default void i_addChat( + JdbcTemplate jdbcTemplate, + long chat + ) { + int chat_id; + + try { + chat_id = jdbcTemplate.query( + "SELECT * FROM tgchats WHERE id=(SELECT MAX(id) FROM tgchats)", + new ChatMapper() + ).get(0).id() + 1; + } catch (IndexOutOfBoundsException e) { + chat_id = 1; + } + + jdbcTemplate.update("INSERT INTO tgchats VALUES(?, ?)", chat_id, chat); + } + + default void i_removeChat( + JdbcTemplate jdbcTemplate, + long chat + ){ + String query = "DELETE FROM tgchats WHERE tg_chat_id=(%d)"; + query = query.formatted(chat); + jdbcTemplate.update(query); + } + + default int i_findChat( + JdbcTemplate jdbcTemplate, + long chat + ){ + try { + String query = "SELECT * FROM tgchats WHERE tg_chat_id=(%d)"; + query = query.formatted(chat); + return jdbcTemplate.query( + query, + new ChatMapper() + ).get(0).id(); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return 0; + } + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkChatOperations.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkChatOperations.java new file mode 100644 index 0000000..e40b248 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkChatOperations.java @@ -0,0 +1,61 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.operations; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.scrapper.model.LinkChatResponse; +import ru.tinkoff.edu.java.scrapper.jdbc.mappers.LinkChatMapper; + +import java.util.List; + +public interface LinkChatOperations { + default void addLinkChat( + JdbcTemplate jdbcTemplate, + int link_id, + int chat_id + ) { + jdbcTemplate.update("INSERT INTO links_tgchats VALUES(?, ?)", link_id, chat_id); + } + + default void i_removeLinkChat( + JdbcTemplate jdbcTemplate, + int link_id, + int chat_id + ) { + String query = "DELETE FROM links_tgchats WHERE linkid=(%d) AND chatid=(%d)"; + query = query.formatted(link_id, chat_id); + jdbcTemplate.update(query); + } + + default void i_removeLinkChatAllChat( + JdbcTemplate jdbcTemplate, + int chat_id + ) { + String query = "DELETE FROM links_tgchats WHERE chatid=(%d)"; + query = query.formatted(chat_id); + jdbcTemplate.update(query); + } + + default boolean i_findLinkChat( + JdbcTemplate jdbcTemplate, + int link_id, + int chat_id + ){ + try { + String query = "SELECT * FROM links_tgchats WHERE linkid=(%d) AND chatid=(%d)"; + query = query.formatted(link_id, chat_id); + jdbcTemplate.query(query, new LinkChatMapper()).get(0); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return true; + } + return false; + } + + default List i_get_all_links_for_chat(JdbcTemplate jdbcTemplate, int chat_id) { + try { + String query = "SELECT * FROM links_tgchats WHERE chatid=(%d)"; + query = query.formatted(chat_id); + return jdbcTemplate.query(query, new LinkChatMapper()); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return null; + } + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkOperations.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkOperations.java new file mode 100644 index 0000000..dfdbe71 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/jdbc/operations/LinkOperations.java @@ -0,0 +1,83 @@ +package ru.tinkoff.edu.java.scrapper.jdbc.operations; + +import org.springframework.jdbc.core.JdbcTemplate; +import ru.tinkoff.edu.java.scrapper.model.AddLinkRequest; +import ru.tinkoff.edu.java.scrapper.model.LinkResponse; +import ru.tinkoff.edu.java.scrapper.model.RemoveLinkRequest; +import ru.tinkoff.edu.java.scrapper.jdbc.mappers.LinkMapper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public interface LinkOperations { + default void i_addLink( + JdbcTemplate jdbcTemplate, + String link + ) { + int link_id; + + try { + link_id = jdbcTemplate.query( + "SELECT * FROM links WHERE id=(SELECT MAX(id) FROM links)", + new LinkMapper() + ).get(0).id() + 1; + } catch (IndexOutOfBoundsException e) { + link_id = 1; + } + + jdbcTemplate.update("INSERT INTO links VALUES(?, ?)", link_id, link); + } + + default void i_removeLink( + JdbcTemplate jdbcTemplate, + String link + ){ + String query = "DELETE FROM links where link IN ('%s')"; + query = query.formatted(link); + jdbcTemplate.update(query); + } + + default List i_findAllLink( + JdbcTemplate jdbcTemplate, + ArrayList links_ids + ){ + try { + String ids = Arrays.toString(links_ids.toArray()); + ids = ids.substring(1, ids.length() - 1); + String query = "SELECT * FROM links WHERE id IN (%s)"; + query = query.formatted(ids); + return jdbcTemplate.query( + query, + new LinkMapper() + ); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return null; + } + } + + default int i_findLink( + JdbcTemplate jdbcTemplate, + String link + ){ + try { + String query = "SELECT * FROM links WHERE link IN ('%s')"; + query = query.formatted(link); + return jdbcTemplate.query( + query, + new LinkMapper() + ).get(0).id(); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return 0; + } + } + + default List i_getAllIds(JdbcTemplate jdbcTemplate) { + try { + String query = "SELECT * FROM links"; + return jdbcTemplate.query(query, new LinkMapper()); + } catch (IndexOutOfBoundsException e) { // Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ нашлось + return null; + } + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/AddLinkRequest.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/AddLinkRequest.java new file mode 100644 index 0000000..e7f8aa4 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/AddLinkRequest.java @@ -0,0 +1,3 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record AddLinkRequest(String link) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ChatResponse.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ChatResponse.java new file mode 100644 index 0000000..d1e1893 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ChatResponse.java @@ -0,0 +1,3 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record ChatResponse(long chat_id, int id) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkChatResponse.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkChatResponse.java new file mode 100644 index 0000000..6ef6a2c --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkChatResponse.java @@ -0,0 +1,3 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record LinkChatResponse(int linkid, int chatid) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkResponse.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkResponse.java new file mode 100644 index 0000000..d5192ab --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkResponse.java @@ -0,0 +1,3 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record LinkResponse(String url, int id) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkUpdate.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkUpdate.java new file mode 100644 index 0000000..ba13a15 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/LinkUpdate.java @@ -0,0 +1,4 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record LinkUpdate(String url) { +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ListLinksResponse.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ListLinksResponse.java new file mode 100644 index 0000000..6a04698 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/ListLinksResponse.java @@ -0,0 +1,6 @@ +package ru.tinkoff.edu.java.scrapper.model; + +import java.util.*; + +public record ListLinksResponse(List links, int size) {} + diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/RemoveLinkRequest.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/RemoveLinkRequest.java new file mode 100644 index 0000000..1f9b6ee --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/RemoveLinkRequest.java @@ -0,0 +1,3 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public record RemoveLinkRequest(String link) {} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/UpdateService.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/UpdateService.java new file mode 100644 index 0000000..4d53819 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/model/UpdateService.java @@ -0,0 +1,4 @@ +package ru.tinkoff.edu.java.scrapper.model; + +public class UpdateService { +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceImplement.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceImplement.java new file mode 100644 index 0000000..8432dad --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceImplement.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +public interface HandleNoticeServiceImplement { + void handleNotification(String message); +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceQueue.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceQueue.java new file mode 100644 index 0000000..deb53c3 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/HandleNoticeServiceQueue.java @@ -0,0 +1,16 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class HandleNoticeServiceQueue implements HandleNoticeServiceImplement { + + Logger log = LoggerFactory.getLogger(HandleNoticeServiceQueue.class); + @Override + public void handleNotification(String message) { + log.info("ΠŸΡ€ΠΈΡˆΠ»ΠΎ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ с Rabbit ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ: " + message); + } +} \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueListener.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueListener.java new file mode 100644 index 0000000..1d587b6 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueListener.java @@ -0,0 +1,19 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import ru.tinkoff.edu.java.scrapper.model.LinkUpdate; + +@RabbitListener(queues = "${app.queue}") +public class ScrapperQueueListener { + private final HandleNoticeServiceQueue handleNoticeServiceQueue; + + public ScrapperQueueListener(HandleNoticeServiceQueue notificationHandler) { + this.handleNoticeServiceQueue = notificationHandler; + } + + @RabbitHandler + public void receiver(LinkUpdate update) { + handleNoticeServiceQueue.handleNotification(update.url()); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueProducer.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueProducer.java new file mode 100644 index 0000000..c592025 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/ScrapperQueueProducer.java @@ -0,0 +1,28 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.tinkoff.edu.java.scrapper.configuration.ApplicationConfig; +import ru.tinkoff.edu.java.scrapper.model.LinkUpdate; + +@Service + +public class ScrapperQueueProducer { + private final RabbitTemplate rabbitTemplate; + + private final ApplicationConfig config; + + public ScrapperQueueProducer(RabbitTemplate rabbitTemplate, ApplicationConfig config) { + this.rabbitTemplate = rabbitTemplate; + this.config = config; + } + + public void send(LinkUpdate update) { + String exchange = config.exchange(); // Имя ΠΎΠ±ΠΌΠ΅Π½Π° + String routingKey = config.routingKey(); // ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ + + rabbitTemplate.convertAndSend(exchange, routingKey, update.url()); + } +} + diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceHttp.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceHttp.java new file mode 100644 index 0000000..7067329 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceHttp.java @@ -0,0 +1,11 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +import org.springframework.stereotype.Service; + +@Service +public class SendNoticeServiceHttp implements SendNoticeServiceImplement { + @Override + public void sendNotice(String message) { + // TO DO WHERE CLIENT + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceImplement.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceImplement.java new file mode 100644 index 0000000..680f7fe --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceImplement.java @@ -0,0 +1,5 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +public interface SendNoticeServiceImplement { + void sendNotice(String notice); +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceQueue.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceQueue.java new file mode 100644 index 0000000..70eed14 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/rabbitmq/SendNoticeServiceQueue.java @@ -0,0 +1,20 @@ +package ru.tinkoff.edu.java.scrapper.rabbitmq; + +import org.springframework.stereotype.Service; +import ru.tinkoff.edu.java.scrapper.model.LinkUpdate; + +@Service +public class SendNoticeServiceQueue implements SendNoticeServiceImplement { + private final ScrapperQueueProducer queueProducer; + + public SendNoticeServiceQueue(ScrapperQueueProducer queueProducer) { + this.queueProducer = queueProducer; + } + + @Override + public void sendNotice(String message) { + // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСния Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Ρ‡Π΅Ρ€Π΅Π· ScrapperQueueProducer + LinkUpdate update = new LinkUpdate(message); + queueProducer.send(update); + } +} diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdaterScheduler.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdaterScheduler.java new file mode 100644 index 0000000..63acc43 --- /dev/null +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/LinkUpdaterScheduler.java @@ -0,0 +1,63 @@ +package ru.tinkoff.edu.java.scrapper.schedule; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import ru.tinkoff.edu.java.linkparser.LinkParser; +import ru.tinkoff.edu.java.scrapper.client.ClientConfiguration; +import ru.tinkoff.edu.java.scrapper.jdbc.JdbcLinkService; +import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; + +import java.lang.ref.Cleaner; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Service +public class LinkUpdaterScheduler implements LinkOperations { +// private final static Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); +// +// private final JdbcTemplate jdbcTemplate; +// ArrayList link_list = new ArrayList<>(); +// static int ix = 0; +// ClientConfiguration client = new ClientConfiguration(); +// LinkParser pars = new LinkParser(); +// boolean git_link_is_activity; +// boolean stack_link_is_activity; +// +// public LinkUpdaterScheduler(JdbcTemplate jdbcTemplate) { +// this.jdbcTemplate = jdbcTemplate; +// } +// +// @Scheduled(fixedDelayString = "${app.scheduler.interval}") +// public void update() { +// int i; +// for (i = 0; i < i_getAllIds(jdbcTemplate).size(); i++){ +// if (!link_list.contains(i_getAllIds(jdbcTemplate).get(i).url())) { +// link_list.add(i_getAllIds(jdbcTemplate).get(i).url()); +// } +// } +// try { +// client.gitHubClient(pars.getLink(link_list.get(ix))); +// git_link_is_activity = true; +// } catch (WebClientResponseException e) { +// git_link_is_activity = false; +// } +// try { +// client.stackOverflowClient(pars.getLink(link_list.get(ix))); +// stack_link_is_activity = true; +// } catch (WebClientResponseException ignored) { +// stack_link_is_activity = false; +// } +// if (!(git_link_is_activity || stack_link_is_activity)) { +// String link = "Бсылка %s устарСла"; +// link = link.formatted(i_getAllIds(jdbcTemplate).get(ix).url()); +// LOGGER.log(Level.INFO, link); +// } +// ix++; +// if (ix == link_list.size()) ix = 0; +// } +} diff --git a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java similarity index 62% rename from FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java rename to FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java index 623f12b..d060c22 100644 --- a/FP/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/schedule/Scheduler.java @@ -2,5 +2,4 @@ import java.time.Duration; -public record Scheduler(Duration interval) { -} \ No newline at end of file +public record Scheduler(Duration interval) {} diff --git a/FP/scrapper/src/main/resources/application.properties b/FP/scrapper/src/main/resources/application.properties new file mode 100644 index 0000000..d4267e9 --- /dev/null +++ b/FP/scrapper/src/main/resources/application.properties @@ -0,0 +1,9 @@ +app.test=123 +springdoc.swagger-ui.path=/swagger-ui +app.scheduler.interval=5000 +git.link=https://github.com/Ray-Not/JavaGuava +stack.link=https://stackoverflow.com/questions/1642028/what-is-the-operator-in-c +app.exchange=my-direct-exchange +app.queue=my-queue +app.routingKey=my-routing-key +app.useQueue=True \ No newline at end of file diff --git a/FP/scrapper/src/test/java/BaseTest.java b/FP/scrapper/src/test/java/BaseTest.java new file mode 100644 index 0000000..447e5c5 --- /dev/null +++ b/FP/scrapper/src/test/java/BaseTest.java @@ -0,0 +1,11 @@ +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class BaseTest extends IntegrationEnvironment { + + @Test + void create_test() { + Assertions.assertTrue(Postgre_container.isCreated()); + System.out.println(Postgre_container.getImage()); + } +} \ No newline at end of file diff --git a/FP/scrapper/src/test/java/IntegrationEnvironment.java b/FP/scrapper/src/test/java/IntegrationEnvironment.java new file mode 100644 index 0000000..7fef825 --- /dev/null +++ b/FP/scrapper/src/test/java/IntegrationEnvironment.java @@ -0,0 +1,45 @@ +import liquibase.Contexts; +import liquibase.LabelExpression; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.LiquibaseException; +import liquibase.resource.DirectoryResourceAccessor; +import org.testcontainers.containers.PostgreSQLContainer; + +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public abstract class IntegrationEnvironment { + + static final protected PostgreSQLContainer Postgre_container; + + static { + Postgre_container = new PostgreSQLContainer<>("postgres:14"); + Postgre_container.start(); + + try { + Connection connection = DriverManager.getConnection( + Postgre_container.getJdbcUrl(), + Postgre_container.getUsername(), + Postgre_container.getPassword()); + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)); + Liquibase liquibase = new liquibase.Liquibase( + "master.xml", + new DirectoryResourceAccessor(Path.of(".") + .toAbsolutePath() + .getParent() + .getParent() + .resolve("migrations")), + database); + liquibase.update(new Contexts(), new LabelExpression()); + } catch (SQLException | LiquibaseException | FileNotFoundException e) { + System.out.println(e.getMessage()); + throw new RuntimeException(e); + } + } +} diff --git a/FP/scrapper/src/test/java/JdbcAddTest.java b/FP/scrapper/src/test/java/JdbcAddTest.java new file mode 100644 index 0000000..d5de9ec --- /dev/null +++ b/FP/scrapper/src/test/java/JdbcAddTest.java @@ -0,0 +1,9 @@ +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class JdbcAddTest extends IntegrationEnvironment { + @Test + void create_test() { +// Postgre_container. + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 From 2ee103a8f3748732626d785ca18c8026c2605044 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:37:08 +0500 Subject: [PATCH 05/61] =?UTF-8?q?Workflows=20=D0=BF=D1=80=D0=B8=D0=B2?= =?UTF-8?q?=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 23 +++++++++++++++++++++++ .github/workflows/scrapper.yml | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 .github/workflows/bot.yml create mode 100644 .github/workflows/scrapper.yml diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml new file mode 100644 index 0000000..50833d9 --- /dev/null +++ b/.github/workflows/bot.yml @@ -0,0 +1,23 @@ +name: Bot Build + +on: + push: + paths: + - 'bot/**' + +jobs: + build: + name: Build Bot + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '11' + + - name: Build Bot Application + run: mvn package -pl bot -am \ No newline at end of file diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml new file mode 100644 index 0000000..bb83328 --- /dev/null +++ b/.github/workflows/scrapper.yml @@ -0,0 +1,23 @@ +name: Scrapper Build + +on: + push: + paths: + - 'scrapper/**' + +jobs: + build: + name: Build Scrapper + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '11' + + - name: Build Scrapper Application + run: mvn package -pl scrapper -am \ No newline at end of file From cc8a642c82d6c956802a9ac486e2a975802e1387 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:39:52 +0500 Subject: [PATCH 06/61] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BB=D0=B5=D0=B2=D0=BE=D0=B3=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B0,=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D0=B0=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/scrapper/src/test/java/JdbcAddTest.java | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 FP/scrapper/src/test/java/JdbcAddTest.java diff --git a/FP/scrapper/src/test/java/JdbcAddTest.java b/FP/scrapper/src/test/java/JdbcAddTest.java deleted file mode 100644 index d5de9ec..0000000 --- a/FP/scrapper/src/test/java/JdbcAddTest.java +++ /dev/null @@ -1,9 +0,0 @@ -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class JdbcAddTest extends IntegrationEnvironment { - @Test - void create_test() { -// Postgre_container. - } -} From fe33f8a9a817a8b160f254cccf7e4e6835706427 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:43:41 +0500 Subject: [PATCH 07/61] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=83=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 2 +- .github/workflows/scrapper.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml index 50833d9..cd972f8 100644 --- a/.github/workflows/bot.yml +++ b/.github/workflows/bot.yml @@ -3,7 +3,7 @@ name: Bot Build on: push: paths: - - 'bot/**' + - 'FP/bot/**' jobs: build: diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index bb83328..fc61f38 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -3,7 +3,7 @@ name: Scrapper Build on: push: paths: - - 'scrapper/**' + - 'FP/scrapper/**' jobs: build: From b20a4d839d3b6adccefca066f21385aa63f02b39 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:47:19 +0500 Subject: [PATCH 08/61] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.github/workflows/bot.yml | 23 +++++++++++++++++++++++ FP/.github/workflows/scrapper.yml | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 FP/.github/workflows/bot.yml create mode 100644 FP/.github/workflows/scrapper.yml diff --git a/FP/.github/workflows/bot.yml b/FP/.github/workflows/bot.yml new file mode 100644 index 0000000..50833d9 --- /dev/null +++ b/FP/.github/workflows/bot.yml @@ -0,0 +1,23 @@ +name: Bot Build + +on: + push: + paths: + - 'bot/**' + +jobs: + build: + name: Build Bot + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '11' + + - name: Build Bot Application + run: mvn package -pl bot -am \ No newline at end of file diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml new file mode 100644 index 0000000..bb83328 --- /dev/null +++ b/FP/.github/workflows/scrapper.yml @@ -0,0 +1,23 @@ +name: Scrapper Build + +on: + push: + paths: + - 'scrapper/**' + +jobs: + build: + name: Build Scrapper + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '11' + + - name: Build Scrapper Application + run: mvn package -pl scrapper -am \ No newline at end of file From bf15ea7b2f84a833046a84c1c90f67a4e0c14d6b Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 19:48:30 +0500 Subject: [PATCH 09/61] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=D1=82=D0=B0=D1=80=D0=BE=D0=B3=D0=BE=20wor?= =?UTF-8?q?kflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 23 ----------------------- .github/workflows/scrapper.yml | 23 ----------------------- 2 files changed, 46 deletions(-) delete mode 100644 .github/workflows/bot.yml delete mode 100644 .github/workflows/scrapper.yml diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml deleted file mode 100644 index cd972f8..0000000 --- a/.github/workflows/bot.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Bot Build - -on: - push: - paths: - - 'FP/bot/**' - -jobs: - build: - name: Build Bot - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - - name: Set up JDK - uses: actions/setup-java@v2 - with: - java-version: '11' - - - name: Build Bot Application - run: mvn package -pl bot -am \ No newline at end of file diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml deleted file mode 100644 index fc61f38..0000000 --- a/.github/workflows/scrapper.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Scrapper Build - -on: - push: - paths: - - 'FP/scrapper/**' - -jobs: - build: - name: Build Scrapper - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - - name: Set up JDK - uses: actions/setup-java@v2 - with: - java-version: '11' - - - name: Build Scrapper Application - run: mvn package -pl scrapper -am \ No newline at end of file From ab3cbb29f1b064e6ed4b8c7522d37f049495a03f Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 20:07:10 +0500 Subject: [PATCH 10/61] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8=3F=3F=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.github/workflows/bot.yml | 2 +- FP/.github/workflows/scrapper.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FP/.github/workflows/bot.yml b/FP/.github/workflows/bot.yml index 50833d9..2fe7611 100644 --- a/FP/.github/workflows/bot.yml +++ b/FP/.github/workflows/bot.yml @@ -17,7 +17,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v2 with: - java-version: '11' + java-version: '20' - name: Build Bot Application run: mvn package -pl bot -am \ No newline at end of file diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml index bb83328..4a19103 100644 --- a/FP/.github/workflows/scrapper.yml +++ b/FP/.github/workflows/scrapper.yml @@ -17,7 +17,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v2 with: - java-version: '11' + java-version: '20' - name: Build Scrapper Application run: mvn package -pl scrapper -am \ No newline at end of file From 69d7e320b683ed5b209405464d5168a9c71a2a09 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 22:02:32 +0500 Subject: [PATCH 11/61] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {FP/.github => .github}/workflows/bot.yml | 0 .../workflows/scrapper.yml | 0 FP/bot/Dockerfile | 29 +++++++++++++++++++ FP/scrapper/Dockerfile | 4 +++ FP/scrapper/pom.xml | 1 + 5 files changed, 34 insertions(+) rename {FP/.github => .github}/workflows/bot.yml (100%) rename {FP/.github => .github}/workflows/scrapper.yml (100%) create mode 100644 FP/bot/Dockerfile create mode 100644 FP/scrapper/Dockerfile diff --git a/FP/.github/workflows/bot.yml b/.github/workflows/bot.yml similarity index 100% rename from FP/.github/workflows/bot.yml rename to .github/workflows/bot.yml diff --git a/FP/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml similarity index 100% rename from FP/.github/workflows/scrapper.yml rename to .github/workflows/scrapper.yml diff --git a/FP/bot/Dockerfile b/FP/bot/Dockerfile new file mode 100644 index 0000000..9a6d58b --- /dev/null +++ b/FP/bot/Dockerfile @@ -0,0 +1,29 @@ +# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π· с установлСнным Java ΠΈ Maven +FROM maven:3.8.4-openjdk-11 AS builder + +# УстанавливаСм Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ +WORKDIR /app + +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ»Ρ‹ Maven ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° +COPY pom.xml . + +# Π‘ΠΊΠ°Ρ‡ΠΈΠ²Π°Π΅ΠΌ зависимости ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° +RUN mvn dependency:go-offline -B + +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ исходный ΠΊΠΎΠ΄ +COPY src ./src + +# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ +RUN mvn package -DskipTests + +# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Docker-ΠΎΠ±Ρ€Π°Π· +FROM openjdk:11-jre-slim + +# УстанавливаСм Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ +WORKDIR /app + +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ JAR Ρ„Π°ΠΉΠ» ΠΈΠ· ΠΎΠ±Ρ€Π°Π·Π° builder +COPY --from=builder /app/target/bot.jar . + +# Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ для запуска Π±ΠΎΡ‚Π° +CMD ["java", "-jar", "bot.jar"] \ No newline at end of file diff --git a/FP/scrapper/Dockerfile b/FP/scrapper/Dockerfile new file mode 100644 index 0000000..6e556d3 --- /dev/null +++ b/FP/scrapper/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:20 +WORKDIR /app/scrapper +COPY target/scrapper-1.0.jar scrapper.jar +ENTRYPOINT ["java", "-jar", "scrapper.jar"] \ No newline at end of file diff --git a/FP/scrapper/pom.xml b/FP/scrapper/pom.xml index fad5590..30db9a3 100644 --- a/FP/scrapper/pom.xml +++ b/FP/scrapper/pom.xml @@ -113,4 +113,5 @@ 3.0.6 + \ No newline at end of file From 2aa74c987a2867161632bce3ca045b30a987c1bb Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 22:05:39 +0500 Subject: [PATCH 12/61] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 2 +- .github/workflows/scrapper.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml index 2fe7611..f718a7b 100644 --- a/.github/workflows/bot.yml +++ b/.github/workflows/bot.yml @@ -3,7 +3,7 @@ name: Bot Build on: push: paths: - - 'bot/**' + - 'FP/bot/**' jobs: build: diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 4a19103..f929d2a 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -3,7 +3,7 @@ name: Scrapper Build on: push: paths: - - 'scrapper/**' + - 'FP/scrapper/**' jobs: build: From da303ece0fef7446825e805a701ef64a323a9caf Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 23:26:30 +0500 Subject: [PATCH 13/61] =?UTF-8?q?=D0=A1=D0=B5=D0=BA=D1=80=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 49 ++++++++++++++----- FP/bot/Dockerfile | 31 ++---------- FP/bot/pom.xml | 25 ++++++++++ FP/pom.xml | 15 +----- FP/scrapper/Dockerfile | 2 +- FP/scrapper/pom.xml | 24 +++++++++ .../java/scrapper/ScrapperApplication.java | 2 +- 7 files changed, 94 insertions(+), 54 deletions(-) diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml index f718a7b..4832485 100644 --- a/.github/workflows/bot.yml +++ b/.github/workflows/bot.yml @@ -1,23 +1,50 @@ -name: Bot Build +name: Bot CI on: push: paths: - - 'FP/bot/**' + - "TinkoffEdu/bot/**" + - "TinkoffEdu/bot.Dockerfile" + - "TinkoffEdu/checkstyle.xml" + - "TinkoffEdu/pom.xml" + - ".github/workflows/bot.yaml" jobs: build: - name: Build Bot runs-on: ubuntu-latest - + permissions: + contents: read + packages: write steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up JDK 19 + uses: actions/setup-java@v3 + with: + java-version: '19' + distribution: 'temurin' + cache: maven + + - name: Build Maven project + run: mvn package -pl bot -am - - name: Set up JDK - uses: actions/setup-java@v2 + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 with: - java-version: '20' + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.JAVAGUAVA }} + + - name: Lowercase repo name + uses: actions/github-script@v6 + id: lowercase_repo + with: + result-encoding: string + script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() + + - name: Build Docker image + run: docker build --file bot.Dockerfile -t ${{ steps.lowercase_repo.outputs.result }}/bot:latest . - - name: Build Bot Application - run: mvn package -pl bot -am \ No newline at end of file + - name: Push Docker image to GitHub Container Registry + run: docker push ${{ steps.lowercase_repo.outputs.result }}/bot:latest \ No newline at end of file diff --git a/FP/bot/Dockerfile b/FP/bot/Dockerfile index 9a6d58b..f9b97e1 100644 --- a/FP/bot/Dockerfile +++ b/FP/bot/Dockerfile @@ -1,29 +1,4 @@ -# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π· с установлСнным Java ΠΈ Maven -FROM maven:3.8.4-openjdk-11 AS builder - -# УстанавливаСм Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ -WORKDIR /app - -# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ„Π°ΠΉΠ»Ρ‹ Maven ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -COPY pom.xml . - -# Π‘ΠΊΠ°Ρ‡ΠΈΠ²Π°Π΅ΠΌ зависимости ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -RUN mvn dependency:go-offline -B - -# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ исходный ΠΊΠΎΠ΄ -COPY src ./src - -# Π‘ΠΎΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ -RUN mvn package -DskipTests - -# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Docker-ΠΎΠ±Ρ€Π°Π· -FROM openjdk:11-jre-slim - -# УстанавливаСм Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ -WORKDIR /app - -# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ JAR Ρ„Π°ΠΉΠ» ΠΈΠ· ΠΎΠ±Ρ€Π°Π·Π° builder -COPY --from=builder /app/target/bot.jar . - -# Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ для запуска Π±ΠΎΡ‚Π° +FROM openjdk:20 +WORKDIR /app/bot +COPY target/bot-1.0.jar bot.jar CMD ["java", "-jar", "bot.jar"] \ No newline at end of file diff --git a/FP/bot/pom.xml b/FP/bot/pom.xml index 96dea0d..58ec92a 100644 --- a/FP/bot/pom.xml +++ b/FP/bot/pom.xml @@ -107,4 +107,29 @@ compile + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + \ No newline at end of file diff --git a/FP/pom.xml b/FP/pom.xml index e38a124..73212ce 100644 --- a/FP/pom.xml +++ b/FP/pom.xml @@ -33,22 +33,10 @@ - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - false - - org.springframework.boot spring-boot-maven-plugin - ${spring-boot.version + ${spring-boot.version} true @@ -69,6 +57,7 @@ + org.apache.maven.plugins maven-compiler-plugin diff --git a/FP/scrapper/Dockerfile b/FP/scrapper/Dockerfile index 6e556d3..453a446 100644 --- a/FP/scrapper/Dockerfile +++ b/FP/scrapper/Dockerfile @@ -1,4 +1,4 @@ FROM openjdk:20 WORKDIR /app/scrapper COPY target/scrapper-1.0.jar scrapper.jar -ENTRYPOINT ["java", "-jar", "scrapper.jar"] \ No newline at end of file +CMD ["java", "-jar", "scrapper.jar"] \ No newline at end of file diff --git a/FP/scrapper/pom.xml b/FP/scrapper/pom.xml index 30db9a3..62e2b12 100644 --- a/FP/scrapper/pom.xml +++ b/FP/scrapper/pom.xml @@ -113,5 +113,29 @@ 3.0.6 + + + + org.springframework.boot + spring-boot-maven-plugin + + + + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + \ No newline at end of file diff --git a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java index 0539e02..db3b685 100644 --- a/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java +++ b/FP/scrapper/src/main/java/ru/tinkoff/edu/java/scrapper/ScrapperApplication.java @@ -24,6 +24,6 @@ public static void main(String[] args) { // config // )); // notificationService.sendNotice("Π’ΠΎΡ‚-Π²ΠΎΡ‚"); -// Cannot invoke "org.springframework.amqp.rabbit.connection.ConnectionFactory.createConnection()" because "connectionFactory" is null +//// Cannot invoke "org.springframework.amqp.rabbit.connection.ConnectionFactory.createConnection()" because "connectionFactory" is null } } From fac3782b39a60a266b114896156c07498d594f09 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 23:31:37 +0500 Subject: [PATCH 14/61] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml index 4832485..7fe6e8c 100644 --- a/.github/workflows/bot.yml +++ b/.github/workflows/bot.yml @@ -3,10 +3,8 @@ name: Bot CI on: push: paths: - - "TinkoffEdu/bot/**" - - "TinkoffEdu/bot.Dockerfile" - - "TinkoffEdu/checkstyle.xml" - - "TinkoffEdu/pom.xml" + - "FP/bot/**" + - "FP/pom.xml" - ".github/workflows/bot.yaml" jobs: From 5b9aa500773ba80074320d0d5582df5ac64579e9 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Fri, 19 May 2023 23:34:04 +0500 Subject: [PATCH 15/61] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20workflows=20scrapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 47 ++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index f929d2a..7fa26f2 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -1,23 +1,48 @@ -name: Scrapper Build +name: Scrapper CI on: push: paths: - - 'FP/scrapper/**' + - "FP/bot/**" + - "FP/pom.xml" + - ".github/workflows/bot.yaml" jobs: build: - name: Build Scrapper runs-on: ubuntu-latest - + permissions: + contents: read + packages: write steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up JDK 19 + uses: actions/setup-java@v3 + with: + java-version: '19' + distribution: 'temurin' + cache: maven + + - name: Build Maven project + run: mvn package -pl bot -am - - name: Set up JDK - uses: actions/setup-java@v2 + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 with: - java-version: '20' + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.JAVAGUAVA }} + + - name: Lowercase repo name + uses: actions/github-script@v6 + id: lowercase_repo + with: + result-encoding: string + script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() + + - name: Build Docker image + run: docker build --file bot.Dockerfile -t ${{ steps.lowercase_repo.outputs.result }}/bot:latest . - - name: Build Scrapper Application - run: mvn package -pl scrapper -am \ No newline at end of file + - name: Push Docker image to GitHub Container Registry + run: docker push ${{ steps.lowercase_repo.outputs.result }}/bot:latest \ No newline at end of file From 9ce98090003e2e7bfd48b3a31cc4b561fc8d201a Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 01:48:05 +0500 Subject: [PATCH 16/61] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BC=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/bot/pom.xml | 11 +++-- .../ru/tinkoff/edu/java/bot/handler/DB.java | 42 ------------------- .../edu/java/bot/handler/commands/List.java | 4 -- .../edu/java/bot/handler/commands/Start.java | 1 - .../edu/java/bot/handler/commands/Track.java | 6 --- .../java/bot/handler/commands/Untrack.java | 1 - 6 files changed, 5 insertions(+), 60 deletions(-) delete mode 100644 FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java diff --git a/FP/bot/pom.xml b/FP/bot/pom.xml index 58ec92a..7825351 100644 --- a/FP/bot/pom.xml +++ b/FP/bot/pom.xml @@ -18,6 +18,11 @@ + + org.example + scrapper + 1.0 + org.springdoc @@ -100,12 +105,6 @@ postgresql runtime - - org.example - scrapper - 1.0 - compile - diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java deleted file mode 100644 index 6b57338..0000000 --- a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/DB.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.tinkoff.edu.java.bot.handler; - -import java.util.ArrayList; - -public class DB { - - static ArrayList list = new ArrayList(); - - public static void addLink(String link) { - list.add(link); - } - - public static void rmLink(String link) { - list.remove(link); - } - - public static String getListParse() { - - int i = 1; - - String out_list = ""; - - for(String element: list){ - - out_list += element; - - if(i != list.size()) { - out_list += ", "; - } - i++; - } - return out_list; - } - - public static boolean listIsEmpty() { - return list.isEmpty(); - } - - public static boolean linkContain(String link) { - return list.contains(link); - } -} diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java index 280f80a..4d21022 100644 --- a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/List.java @@ -1,11 +1,7 @@ package ru.tinkoff.edu.java.bot.handler.commands; -import com.google.gson.JsonObject; -import okhttp3.Interceptor; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; -import ru.tinkoff.edu.java.bot.handler.DB; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.UnauthorizationException; import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java index d2d5459..052a171 100644 --- a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Start.java @@ -1,7 +1,6 @@ package ru.tinkoff.edu.java.bot.handler.commands; import org.springframework.jdbc.core.JdbcTemplate; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryExsistException; import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; public interface Start extends ChatOperations { diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java index 9080b48..f0bfd43 100644 --- a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Track.java @@ -2,17 +2,11 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.reactive.function.client.WebClientResponseException; -import ru.tinkoff.edu.java.bot.handler.DB; import ru.tinkoff.edu.java.linkparser.LinkParser; import ru.tinkoff.edu.java.scrapper.client.ClientConfiguration; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryExsistException; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.EntryNotExsistException; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.NullLinkException; -import ru.tinkoff.edu.java.scrapper.exceptions.customExceptions.UnauthorizationException; import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; -import ru.tinkoff.edu.java.scrapper.model.RemoveLinkRequest; public interface Track extends LinkOperations, LinkChatOperations, ChatOperations { default String track(JdbcTemplate jdbc, String link, long chat) { diff --git a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java index 6615feb..30aafae 100644 --- a/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java +++ b/FP/bot/src/main/java/ru/tinkoff/edu/java/bot/handler/commands/Untrack.java @@ -1,7 +1,6 @@ package ru.tinkoff.edu.java.bot.handler.commands; import org.springframework.jdbc.core.JdbcTemplate; -import ru.tinkoff.edu.java.bot.handler.DB; import ru.tinkoff.edu.java.scrapper.jdbc.operations.ChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkChatOperations; import ru.tinkoff.edu.java.scrapper.jdbc.operations.LinkOperations; From c5b88b50fc9bb8844f9dde1ee330844a987ac1dc Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 02:58:58 +0500 Subject: [PATCH 17/61] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B1=D0=BB=D0=B5?= =?UTF-8?q?=D0=BC=D0=B0=20=D1=81=20package=20bot=20=D0=BD=D0=B5=20=D1=80?= =?UTF-8?q?=D0=B5=D1=88=D0=B5=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bot.yml | 48 ---------------- .github/workflows/scrapper.yml | 50 +++++----------- FP/bot/pom.xml | 11 ++-- FP/link-parser/pom.xml | 55 ++++++++++++++++-- FP/pom.xml | 101 ++++++++++++++++----------------- FP/scrapper/pom.xml | 84 +++++++++++++++------------ 6 files changed, 168 insertions(+), 181 deletions(-) delete mode 100644 .github/workflows/bot.yml diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml deleted file mode 100644 index 7fe6e8c..0000000 --- a/.github/workflows/bot.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Bot CI - -on: - push: - paths: - - "FP/bot/**" - - "FP/pom.xml" - - ".github/workflows/bot.yaml" - -jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up JDK 19 - uses: actions/setup-java@v3 - with: - java-version: '19' - distribution: 'temurin' - cache: maven - - - name: Build Maven project - run: mvn package -pl bot -am - - - name: Login to GitHub Container Registry - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.JAVAGUAVA }} - - - name: Lowercase repo name - uses: actions/github-script@v6 - id: lowercase_repo - with: - result-encoding: string - script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() - - - name: Build Docker image - run: docker build --file bot.Dockerfile -t ${{ steps.lowercase_repo.outputs.result }}/bot:latest . - - - name: Push Docker image to GitHub Container Registry - run: docker push ${{ steps.lowercase_repo.outputs.result }}/bot:latest \ No newline at end of file diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 7fa26f2..b1b6769 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -1,48 +1,26 @@ -name: Scrapper CI +name: Scrapper Build on: push: paths: - - "FP/bot/**" - - "FP/pom.xml" - - ".github/workflows/bot.yaml" + - '.FP/scrapper/**' + pull_request: + paths: + - '.FP/scrapper/**' + - '.github/workflows/scrapper.yml' # Include this path to trigger the workflow when changes are made to the workflow file itself jobs: build: runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up JDK 19 - uses: actions/setup-java@v3 - with: - java-version: '19' - distribution: 'temurin' - cache: maven - - name: Build Maven project - run: mvn package -pl bot -am - - - name: Login to GitHub Container Registry - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.JAVAGUAVA }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 - - name: Lowercase repo name - uses: actions/github-script@v6 - id: lowercase_repo + - name: Set up JDK 20 + uses: actions/setup-java@v2 with: - result-encoding: string - script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() - - - name: Build Docker image - run: docker build --file bot.Dockerfile -t ${{ steps.lowercase_repo.outputs.result }}/bot:latest . + java-version: 20 - - name: Push Docker image to GitHub Container Registry - run: docker push ${{ steps.lowercase_repo.outputs.result }}/bot:latest \ No newline at end of file + - name: Build and package scrapper + run: mvn package -pl scrapper -am diff --git a/FP/bot/pom.xml b/FP/bot/pom.xml index 7825351..58ec92a 100644 --- a/FP/bot/pom.xml +++ b/FP/bot/pom.xml @@ -18,11 +18,6 @@ - - org.example - scrapper - 1.0 - org.springdoc @@ -105,6 +100,12 @@ postgresql runtime + + org.example + scrapper + 1.0 + compile + diff --git a/FP/link-parser/pom.xml b/FP/link-parser/pom.xml index 088df38..8de37c0 100644 --- a/FP/link-parser/pom.xml +++ b/FP/link-parser/pom.xml @@ -3,24 +3,71 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - org.example FP + org.example 1.0 - 4.0.0 link-parser + + + 17 + 17 + 5.8.2 + 4.5.1 + + org.junit.jupiter - junit-jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} test org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + 3.0.0 + maven-plugin + + + org.projectlombok + lombok + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + + \ No newline at end of file diff --git a/FP/pom.xml b/FP/pom.xml index 73212ce..a023481 100644 --- a/FP/pom.xml +++ b/FP/pom.xml @@ -1,16 +1,22 @@ - - + + 4.0.0 - org.example - FP - + 1.0 pom - 1.0 + FP + + + UTF-8 + 19 + 19 + 2022.0.0 + 3.0.1 + 3.10.1 + 1.17.6 + bot @@ -18,17 +24,42 @@ scrapper - - UTF-8 - 17 - 17 - 3.8.1 - 3.0.1 - 2022.0.0 - 23.1.0 - 5.8.1 - 1.18.0 - + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + + + + + org.jetbrains + annotations + 23.1.0 + provided + + @@ -70,36 +101,4 @@ - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - org.jetbrains - annotations - ${annotations.version} - provided - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - \ No newline at end of file diff --git a/FP/scrapper/pom.xml b/FP/scrapper/pom.xml index 62e2b12..e214fdf 100644 --- a/FP/scrapper/pom.xml +++ b/FP/scrapper/pom.xml @@ -1,118 +1,129 @@ - + + 4.0.0 - org.example FP + org.example 1.0 - 4.0.0 - + org.example scrapper + 1.0 + + scrapper - 3.0.1 - 2.7.6 + UTF-8 + 19 + 19 - - - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.0.2 - - org.springframework.boot - spring-boot-starter-validation - ${starter-validation.version} + spring-boot-starter-web + org.springframework.boot - spring-boot-starter-web - ${starter-web.version} + spring-boot-starter-validation + org.springframework.boot spring-boot-devtools runtime true + org.springframework.boot spring-boot-configuration-processor true + org.springframework spring-context-indexer true + org.projectlombok lombok true - + - org.example - link-parser - 1.0 - compile + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.0.2 - - + org.springframework.boot spring-boot-starter-webflux - 3.0.5 - + org.testcontainers junit-jupiter test + org.testcontainers postgresql test + org.liquibase liquibase-core test - + org.springframework.boot spring-boot-starter-jdbc + org.postgresql postgresql runtime + - org.junit.jupiter - junit-jupiter + org.example + link-parser + 1.0 + compile + + + + org.springframework.boot + spring-boot-starter-test test + - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 + org.springframework.boot + spring-boot-starter-jooq - + + + org.springframework.boot + spring-boot-starter-data-jpa + + org.springframework.boot spring-boot-starter-amqp - 3.0.6 + @@ -137,5 +148,4 @@ - \ No newline at end of file From 739b32f688b590e3763e0391ae006cccb8f7ea60 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:01:40 +0500 Subject: [PATCH 18/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index b1b6769..c449766 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -17,10 +17,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - - name: Set up JDK 20 + - name: Set up JDK 11 uses: actions/setup-java@v2 with: - java-version: 20 + java-version: 11 - name: Build and package scrapper run: mvn package -pl scrapper -am From 702aa976f02bd816fecbe700ff038f9ba42d1ec0 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:09:53 +0500 Subject: [PATCH 19/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index c449766..49c8a12 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -14,13 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: 11 - - - name: Build and package scrapper - run: mvn package -pl scrapper -am + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Run the Maven verify phase + run: mvn --batch-mode --update-snapshots verify From 54d943b459ca1d59e13de694807d489df851d6cf Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:13:55 +0500 Subject: [PATCH 20/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 49c8a12..f16d6f0 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/setup-java@v3 with: java-version: '17' - distribution: 'temurin' + distribution: 'ubuntu-latest' - name: Run the Maven verify phase run: mvn --batch-mode --update-snapshots verify From 5c63d1b2c6cf99a2d1b0be8e2f400b5f55b92834 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:16:33 +0500 Subject: [PATCH 21/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index f16d6f0..bacb0da 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -12,12 +12,18 @@ on: jobs: build: runs-on: ubuntu-latest + inputs: + distribution: ubuntu-lates + required: true steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'ubuntu-latest' - - name: Run the Maven verify phase - run: mvn --batch-mode --update-snapshots verify + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: 11 + + - name: Build and package scrapper + run: mvn package -pl scrapper -am From 13e91a0dffd8c63688f272aed49b28ae24dfcb8d Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:18:10 +0500 Subject: [PATCH 22/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index bacb0da..c449766 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -12,9 +12,6 @@ on: jobs: build: runs-on: ubuntu-latest - inputs: - distribution: ubuntu-lates - required: true steps: - name: Checkout repository From d04960e9fc7dbfa69180f2152578f95a96b41fa2 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:20:33 +0500 Subject: [PATCH 23/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index c449766..0b904c6 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -13,6 +13,11 @@ jobs: build: runs-on: ubuntu-latest + inputs: + distribution: + description: 'Distribution of the application' + required: true + steps: - name: Checkout repository uses: actions/checkout@v2 From a5762ced61cd05c44d2f51065357b371d87c02ae Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:22:41 +0500 Subject: [PATCH 24/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 0b904c6..38d2f7c 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -13,10 +13,8 @@ jobs: build: runs-on: ubuntu-latest - inputs: - distribution: - description: 'Distribution of the application' - required: true + env: + DISTRIBUTION: ${{ github.event.inputs.distribution }} steps: - name: Checkout repository @@ -28,4 +26,5 @@ jobs: java-version: 11 - name: Build and package scrapper - run: mvn package -pl scrapper -am + run: | + mvn package -pl scrapper -am From 5788ba9ad9c2f571b579d5243d7f08a81696efaa Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:25:41 +0500 Subject: [PATCH 25/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 38d2f7c..ce6ee9c 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -1,30 +1,27 @@ -name: Scrapper Build +name: Scrapper CI on: push: paths: - - '.FP/scrapper/**' - pull_request: - paths: - - '.FP/scrapper/**' - - '.github/workflows/scrapper.yml' # Include this path to trigger the workflow when changes are made to the workflow file itself + - ".FP/scrapper/**" + - ".github/workflows/scrapper.yaml" jobs: build: runs-on: ubuntu-latest - - env: - DISTRIBUTION: ${{ github.event.inputs.distribution }} - + permissions: + contents: read + packages: write steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v2 + - name: Set up JDK 19 + uses: actions/setup-java@v3 with: - java-version: 11 + java-version: '19' + distribution: 'temurin' + cache: maven - - name: Build and package scrapper - run: | - mvn package -pl scrapper -am + - name: Build Maven project + run: mvn package -pl scrapper -am \ No newline at end of file From 850428d76b6f4593ed5c3d1184d62037a98fc205 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:27:55 +0500 Subject: [PATCH 26/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20CI9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index ce6ee9c..a3776d1 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -1,4 +1,4 @@ -name: Scrapper CI +name: Scrapper Build on: push: From e40db0dbe6817a82bdde6c0d078f06be65fb22f6 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:30:34 +0500 Subject: [PATCH 27/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {.github => FP/.github}/workflows/scrapper.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {.github => FP/.github}/workflows/scrapper.yml (100%) diff --git a/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml similarity index 100% rename from .github/workflows/scrapper.yml rename to FP/.github/workflows/scrapper.yml From 4ae09b0afee6fd920d6ea9662e85f67948fe24e4 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:31:49 +0500 Subject: [PATCH 28/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.github/workflows/scrapper.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml index a3776d1..0e7bf95 100644 --- a/FP/.github/workflows/scrapper.yml +++ b/FP/.github/workflows/scrapper.yml @@ -3,8 +3,7 @@ name: Scrapper Build on: push: paths: - - ".FP/scrapper/**" - - ".github/workflows/scrapper.yaml" + - "FP/scrapper/**" jobs: build: From d9d08aada5ffddc3a790d8e34e0603c2c832d84a Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:33:47 +0500 Subject: [PATCH 29/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 30 ++++++++++++++++++++++++++++++ FP/.github/workflows/scrapper.yml | 26 -------------------------- 2 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/scrapper.yml delete mode 100644 FP/.github/workflows/scrapper.yml diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml new file mode 100644 index 0000000..b0793f2 --- /dev/null +++ b/.github/workflows/scrapper.yml @@ -0,0 +1,30 @@ +name: Scrapper Build + +on: + push: + paths: + - '.FP/scrapper/**' + pull_request: + paths: + - '.FP/scrapper/**' + - '.github/workflows/scrapper.yml' # Include this path to trigger the workflow when changes are made to the workflow file itself + +jobs: + build: + runs-on: ubuntu-latest + + env: + DISTRIBUTION: ${{ github.event.inputs.distribution }} + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: 11 + + - name: Build and package scrapper + run: | + mvn package -pl scrapper -am \ No newline at end of file diff --git a/FP/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml deleted file mode 100644 index 0e7bf95..0000000 --- a/FP/.github/workflows/scrapper.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Scrapper Build - -on: - push: - paths: - - "FP/scrapper/**" - -jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up JDK 19 - uses: actions/setup-java@v3 - with: - java-version: '19' - distribution: 'temurin' - cache: maven - - - name: Build Maven project - run: mvn package -pl scrapper -am \ No newline at end of file From 8d9f2510059ddb3f5784da300c1390c0972bbff0 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:36:35 +0500 Subject: [PATCH 30/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2012?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index b0793f2..a7be867 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -13,17 +13,19 @@ jobs: build: runs-on: ubuntu-latest - env: - DISTRIBUTION: ${{ github.event.inputs.distribution }} + distribution: + description: 'Distribution of the application' + required: true + default: 'ubuntu-latest' steps: - name: Checkout repository uses: actions/checkout@v2 - - name: Set up JDK 11 + - name: Set up JDK 20 uses: actions/setup-java@v2 with: - java-version: 11 + java-version: 20 - name: Build and package scrapper run: | From c4dd3bc3cd02a178a8c6cfe3f2f0c2a0a8830906 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:39:45 +0500 Subject: [PATCH 31/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2013?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index a7be867..e582ef9 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -13,20 +13,12 @@ jobs: build: runs-on: ubuntu-latest - distribution: - description: 'Distribution of the application' - required: true - default: 'ubuntu-latest' - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up JDK 20 - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: 20 - - - name: Build and package scrapper - run: | - mvn package -pl scrapper -am \ No newline at end of file + java-version: '17' + distribution: 'temurin' + - name: Build with Maven + run: mvn package \ No newline at end of file From 520022edf5d194cbfbff12f629b0ce709e74e8dd Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:41:43 +0500 Subject: [PATCH 32/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2014?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index e582ef9..6250dd8 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -21,4 +21,4 @@ jobs: java-version: '17' distribution: 'temurin' - name: Build with Maven - run: mvn package \ No newline at end of file + run: mvn package -pl scrapper -am \ No newline at end of file From 3a6bdd6718046d3e45ae04865d0e04cb6a201ae4 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:43:26 +0500 Subject: [PATCH 33/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2015?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6250dd8..dd5c4ac 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -14,11 +14,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' + - name: Build with Maven - run: mvn package -pl scrapper -am \ No newline at end of file + run: mvn package -pl scrapper -am From dcc947f1f9104dfd06ab810fbb3b26214089f9ef Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:45:24 +0500 Subject: [PATCH 34/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index dd5c4ac..2a3df2f 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -3,10 +3,10 @@ name: Scrapper Build on: push: paths: - - '.FP/scrapper/**' + - '../FP/scrapper/**' pull_request: paths: - - '.FP/scrapper/**' + - '../FP/scrapper/**' - '.github/workflows/scrapper.yml' # Include this path to trigger the workflow when changes are made to the workflow file itself jobs: From e58a31c16b8290a8d23880271077282f6580c8c2 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:48:10 +0500 Subject: [PATCH 35/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2017?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 2a3df2f..649a073 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -7,12 +7,14 @@ on: pull_request: paths: - '../FP/scrapper/**' - - '.github/workflows/scrapper.yml' # Include this path to trigger the workflow when changes are made to the workflow file itself + - '.github/workflows/scrapper.yml' jobs: build: runs-on: ubuntu-latest - + permissions: + contents: read + packages: write steps: - name: Checkout repository uses: actions/checkout@v3 From f24afe08e49aa3728be4c49728d97629fc95ab63 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:49:59 +0500 Subject: [PATCH 36/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2018?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 649a073..6d5079b 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -3,10 +3,10 @@ name: Scrapper Build on: push: paths: - - '../FP/scrapper/**' + - 'FP/scrapper/**' pull_request: paths: - - '../FP/scrapper/**' + - 'FP/scrapper/**' - '.github/workflows/scrapper.yml' jobs: @@ -19,10 +19,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Set up JDK 17 + - name: Set up JDK 20 uses: actions/setup-java@v3 with: - java-version: '17' + java-version: '20' distribution: 'temurin' - name: Build with Maven From 2a2c1cdb00f53da86a6029b27af7857cd44587ff Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:52:45 +0500 Subject: [PATCH 37/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2019?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {.github => FP/.github}/workflows/scrapper.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {.github => FP/.github}/workflows/scrapper.yml (100%) diff --git a/.github/workflows/scrapper.yml b/FP/.github/workflows/scrapper.yml similarity index 100% rename from .github/workflows/scrapper.yml rename to FP/.github/workflows/scrapper.yml From 6c1901ec4f6b51e966a6f9b0b14f9ff5e373e4e4 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:54:05 +0500 Subject: [PATCH 38/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2020?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {FP/.github => .github}/workflows/scrapper.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {FP/.github => .github}/workflows/scrapper.yml (100%) diff --git a/FP/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml similarity index 100% rename from FP/.github/workflows/scrapper.yml rename to .github/workflows/scrapper.yml From 2ebb200bf930cb6d5d2a90efa6f80165955650c0 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 03:58:08 +0500 Subject: [PATCH 39/61] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=2021?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6d5079b..f7c20b2 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -4,6 +4,7 @@ on: push: paths: - 'FP/scrapper/**' + - 'FP/pom.xml' pull_request: paths: - 'FP/scrapper/**' @@ -24,6 +25,7 @@ jobs: with: java-version: '20' distribution: 'temurin' + cache: maven - name: Build with Maven - run: mvn package -pl scrapper -am + run: cd FP && mvn package -pl scrapper -am From 6d09d45be643f4a5a3acaeb563647c56e0bd2e61 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:01:43 +0500 Subject: [PATCH 40/61] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index f7c20b2..6012cf0 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -29,3 +29,7 @@ jobs: - name: Build with Maven run: cd FP && mvn package -pl scrapper -am + + + - name: Build scrapper Docker image + run: docker build -t scrapper-image -f Dockerfile . From 9b3bc28e495a6bf18ba9efc2984fb04c32a0ad37 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:03:56 +0500 Subject: [PATCH 41/61] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6012cf0..222d5bf 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -32,4 +32,4 @@ jobs: - name: Build scrapper Docker image - run: docker build -t scrapper-image -f Dockerfile . + run: cd scrapper && docker build -t scrapper-image -f Dockerfile . From 2442f91efa8e0f357ad19da9236b1ef9853ffdcf Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:06:11 +0500 Subject: [PATCH 42/61] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- FP/{scrapper/Dockerfile => scrapper.Dockerfile} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename FP/{scrapper/Dockerfile => scrapper.Dockerfile} (100%) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 222d5bf..6012cf0 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -32,4 +32,4 @@ jobs: - name: Build scrapper Docker image - run: cd scrapper && docker build -t scrapper-image -f Dockerfile . + run: docker build -t scrapper-image -f Dockerfile . diff --git a/FP/scrapper/Dockerfile b/FP/scrapper.Dockerfile similarity index 100% rename from FP/scrapper/Dockerfile rename to FP/scrapper.Dockerfile From d8ce43d94da34b78270cd9e38d38c334a65df8db Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:07:44 +0500 Subject: [PATCH 43/61] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6012cf0..31eaa7a 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -32,4 +32,4 @@ jobs: - name: Build scrapper Docker image - run: docker build -t scrapper-image -f Dockerfile . + run: docker build -t scrapper-image -f scrapper.Dockerfile . From a22009a77e7432ce11491aa181af1727ce3c2631 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:09:06 +0500 Subject: [PATCH 44/61] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 31eaa7a..5a215c9 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -32,4 +32,4 @@ jobs: - name: Build scrapper Docker image - run: docker build -t scrapper-image -f scrapper.Dockerfile . + run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . From 6c19564f4c989bcc2edc16d9f917f541c10d91be Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:25:54 +0500 Subject: [PATCH 45/61] =?UTF-8?q?=D0=9E=D1=82=D0=BA=D0=B0=D1=82=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=BD=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/scrapper.Dockerfile | 2 +- FP/scrapper/pom.xml | 74 ++++++++++++++++++++---------------------- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/FP/scrapper.Dockerfile b/FP/scrapper.Dockerfile index 453a446..e8d2a7c 100644 --- a/FP/scrapper.Dockerfile +++ b/FP/scrapper.Dockerfile @@ -1,4 +1,4 @@ FROM openjdk:20 WORKDIR /app/scrapper -COPY target/scrapper-1.0.jar scrapper.jar +COPY scrapper/target/scrapper-1.0.jar scrapper.jar CMD ["java", "-jar", "scrapper.jar"] \ No newline at end of file diff --git a/FP/scrapper/pom.xml b/FP/scrapper/pom.xml index e214fdf..2128293 100644 --- a/FP/scrapper/pom.xml +++ b/FP/scrapper/pom.xml @@ -1,94 +1,96 @@ - - 4.0.0 + - FP org.example + FP 1.0 - org.example - scrapper - 1.0 + 4.0.0 - scrapper + scrapper - UTF-8 - 19 - 19 + 3.0.1 + 2.7.6 + - org.springframework.boot - spring-boot-starter-web + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.0.2 - + org.springframework.boot spring-boot-starter-validation + ${starter-validation.version} + + + org.springframework.boot + spring-boot-starter-web + ${starter-web.version} - org.springframework.boot spring-boot-devtools runtime true - org.springframework.boot spring-boot-configuration-processor true - org.springframework spring-context-indexer true - org.projectlombok lombok true - + - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.0.2 + org.example + link-parser + 1.0 + compile - + + org.springframework.boot spring-boot-starter-webflux + 3.0.5 - + org.testcontainers junit-jupiter test - org.testcontainers postgresql test - org.liquibase liquibase-core test - + org.springframework.boot spring-boot-starter-jdbc - org.postgresql postgresql @@ -103,24 +105,20 @@ - org.springframework.boot - spring-boot-starter-test + org.junit.jupiter + junit-jupiter test - - - org.springframework.boot - spring-boot-starter-jooq - - - org.springframework.boot - spring-boot-starter-data-jpa + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 - + org.springframework.boot spring-boot-starter-amqp + 3.0.6 From 5dcf5c0e8089f5bb4bdcc30dbcb5fe63ead37f02 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:47:15 +0500 Subject: [PATCH 46/61] Git publisher --- .github/workflows/scrapper.yml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 5a215c9..6bcde87 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -10,6 +10,10 @@ on: - 'FP/scrapper/**' - '.github/workflows/scrapper.yml' +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build: runs-on: ubuntu-latest @@ -30,6 +34,18 @@ jobs: - name: Build with Maven run: cd FP && mvn package -pl scrapper -am - - - name: Build scrapper Docker image - run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + file: FP/scrapper.Dockerfile + push: ${{ github.ref_type == 'tag' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 40c79c48d2dbf4ef9dc5fa1dcd311b35ee399958 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:56:04 +0500 Subject: [PATCH 47/61] Git publisher --- .github/workflows/scrapper.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6bcde87..e199e3b 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -45,7 +45,6 @@ jobs: uses: docker/build-push-action@v3 with: context: . - file: FP/scrapper.Dockerfile - push: ${{ github.ref_type == 'tag' }} + push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 3f82effa86e563545830e0cb0bf96ca897ee9ca1 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 04:58:25 +0500 Subject: [PATCH 48/61] Git publisher --- .github/workflows/scrapper.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index e199e3b..c897690 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -17,9 +17,6 @@ env: jobs: build: runs-on: ubuntu-latest - permissions: - contents: read - packages: write steps: - name: Checkout repository uses: actions/checkout@v3 @@ -45,6 +42,5 @@ jobs: uses: docker/build-push-action@v3 with: context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + dockerfile: FP/scrapper.Dockerfile + image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From 9964605dae9b6e08344c3f5a0250f71c9ca92860 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:03:30 +0500 Subject: [PATCH 49/61] Git publisher --- .github/workflows/scrapper.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index c897690..aebcb19 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -39,8 +39,6 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v2 with: context: . - dockerfile: FP/scrapper.Dockerfile - image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From 6bbc8fbac463098b0ec344655dd3eacc06facab6 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:09:20 +0500 Subject: [PATCH 50/61] Git publisher --- .github/workflows/scrapper.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index aebcb19..ec5d85b 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -17,6 +17,9 @@ env: jobs: build: runs-on: ubuntu-latest + permissions: + contents: read + packages: write steps: - name: Checkout repository uses: actions/checkout@v3 @@ -37,8 +40,9 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v2 - with: - context: . + + - name: Build scrapper Docker image + run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . + + - name: Push Docker image to GitHub Container Registry + run: docker push javaguava/scrapper:latest From 110679805d6a40750b4696361db4cb701fb2b258 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:11:40 +0500 Subject: [PATCH 51/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index ec5d85b..86f0571 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -45,4 +45,4 @@ jobs: run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . - name: Push Docker image to GitHub Container Registry - run: docker push javaguava/scrapper:latest + run: docker push ghcr.io/javaguava/scrapper:latest From 037b81ae7847de0c2787fa6b0659388a73094538 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:18:28 +0500 Subject: [PATCH 52/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 86f0571..36c5c3a 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -45,4 +45,4 @@ jobs: run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . - name: Push Docker image to GitHub Container Registry - run: docker push ghcr.io/javaguava/scrapper:latest + run: docker push ghcr.io/${{ github.repository }}/scrapper:latest From 5d1d6843c325c0762429b64cc842e40b3ad1f6f0 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:20:22 +0500 Subject: [PATCH 53/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 36c5c3a..3837cb2 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -45,4 +45,4 @@ jobs: run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . - name: Push Docker image to GitHub Container Registry - run: docker push ghcr.io/${{ github.repository }}/scrapper:latest + run: docker push ghcr.io/ray-not/javaguava/scrapper:latest From 9cecb09cfbc30e639cb73796f56ae481f728b1e5 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:22:49 +0500 Subject: [PATCH 54/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 3837cb2..6517e62 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -42,7 +42,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build scrapper Docker image - run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile . + run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile ray-not/javaguava/scrapper:latest - name: Push Docker image to GitHub Container Registry run: docker push ghcr.io/ray-not/javaguava/scrapper:latest From 56a5971f12f8006cff938de32b831f9e74048daa Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:25:53 +0500 Subject: [PATCH 55/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 6517e62..f40f505 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -42,7 +42,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build scrapper Docker image - run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile ray-not/javaguava/scrapper:latest + run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile -t ray-not/javaguava/scrapper:latest - name: Push Docker image to GitHub Container Registry run: docker push ghcr.io/ray-not/javaguava/scrapper:latest From 6714c6109cc2ecb1de934d7b1763319db5161b06 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:28:23 +0500 Subject: [PATCH 56/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index f40f505..5c8b024 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -42,7 +42,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build scrapper Docker image - run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile -t ray-not/javaguava/scrapper:latest + run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile -t ray-not/javaguava/scrapper:latest . - name: Push Docker image to GitHub Container Registry run: docker push ghcr.io/ray-not/javaguava/scrapper:latest From efd38ae7f869d856de9e920fb6390dd1e1c343f6 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 05:35:09 +0500 Subject: [PATCH 57/61] Git publisher --- .github/workflows/scrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index 5c8b024..fef2745 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -42,7 +42,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build scrapper Docker image - run: cd FP && docker build -t scrapper-image -f scrapper.Dockerfile -t ray-not/javaguava/scrapper:latest . + run: cd FP && docker build -f scrapper.Dockerfile -t ghcr.io/ray-not/javaguava/scrapper:latest . - name: Push Docker image to GitHub Container Registry run: docker push ghcr.io/ray-not/javaguava/scrapper:latest From 6a2eca1dab698c21aeaf5fd9026a124649f109f9 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 06:37:38 +0500 Subject: [PATCH 58/61] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=202=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D0=B8=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/scrapper.yml | 16 ++++++++++++++++ FP/.editorconfig | 17 +++++++++++++++++ FP/checkstyle.xml | 11 +++++++++++ 3 files changed, 44 insertions(+) create mode 100644 FP/.editorconfig create mode 100644 FP/checkstyle.xml diff --git a/.github/workflows/scrapper.yml b/.github/workflows/scrapper.yml index fef2745..d2f9670 100644 --- a/.github/workflows/scrapper.yml +++ b/.github/workflows/scrapper.yml @@ -46,3 +46,19 @@ jobs: - name: Push Docker image to GitHub Container Registry run: docker push ghcr.io/ray-not/javaguava/scrapper:latest + checkstyle: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up JDK 20 + uses: actions/setup-java@v3 + with: + java-version: '20' + distribution: 'temurin' + + - name: Format code + run: cd FP && mvn -pl scrapper -am checkstyle:check diff --git a/FP/.editorconfig b/FP/.editorconfig new file mode 100644 index 0000000..7f7a11a --- /dev/null +++ b/FP/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +charset = utf-8 +tab_width = 4 +indent_size = 4 +indent_style = space +max_line_length = 120 +insert_final_newline = true +trim_trailing_whitespace = true +ij_continuation_indent_size = 4 + +[*.java] +ij_java_imports_layout = *, $* +ij_java_packages_to_use_import_on_demand = "" +ij_java_class_count_to_use_import_on_demand = 999 +ij_java_names_count_to_use_import_on_demand = 999 \ No newline at end of file diff --git a/FP/checkstyle.xml b/FP/checkstyle.xml new file mode 100644 index 0000000..d22c8f5 --- /dev/null +++ b/FP/checkstyle.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file From cacba8bae516670568fee942e16716f8bf7bbbf6 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 06:40:38 +0500 Subject: [PATCH 59/61] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=202=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D0=B8=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.editorconfig | 11 +---------- FP/checkstyle.xml | 2 -- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/FP/.editorconfig b/FP/.editorconfig index 7f7a11a..e9187c4 100644 --- a/FP/.editorconfig +++ b/FP/.editorconfig @@ -2,16 +2,7 @@ root = true [*] charset = utf-8 -tab_width = 4 -indent_size = 4 -indent_style = space -max_line_length = 120 -insert_final_newline = true -trim_trailing_whitespace = true ij_continuation_indent_size = 4 [*.java] -ij_java_imports_layout = *, $* -ij_java_packages_to_use_import_on_demand = "" -ij_java_class_count_to_use_import_on_demand = 999 -ij_java_names_count_to_use_import_on_demand = 999 \ No newline at end of file +ij_java_packages_to_use_import_on_demand = "" \ No newline at end of file diff --git a/FP/checkstyle.xml b/FP/checkstyle.xml index d22c8f5..f6fa8d9 100644 --- a/FP/checkstyle.xml +++ b/FP/checkstyle.xml @@ -4,8 +4,6 @@ - - \ No newline at end of file From d030c2b11dd2ce1ac70b9a8430099afdb38c4067 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 06:48:30 +0500 Subject: [PATCH 60/61] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B2=20pom=20link=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D1=81=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.editorconfig | 4 +--- FP/checkstyle.xml | 5 ----- FP/link-parser/pom.xml | 5 ----- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/FP/.editorconfig b/FP/.editorconfig index e9187c4..b43f001 100644 --- a/FP/.editorconfig +++ b/FP/.editorconfig @@ -2,7 +2,5 @@ root = true [*] charset = utf-8 -ij_continuation_indent_size = 4 -[*.java] -ij_java_packages_to_use_import_on_demand = "" \ No newline at end of file +[*.java] \ No newline at end of file diff --git a/FP/checkstyle.xml b/FP/checkstyle.xml index f6fa8d9..76dd56a 100644 --- a/FP/checkstyle.xml +++ b/FP/checkstyle.xml @@ -2,8 +2,3 @@ "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> - - - - - \ No newline at end of file diff --git a/FP/link-parser/pom.xml b/FP/link-parser/pom.xml index 8de37c0..b9572e6 100644 --- a/FP/link-parser/pom.xml +++ b/FP/link-parser/pom.xml @@ -62,11 +62,6 @@ maven-failsafe-plugin 2.22.2 - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - From ec0000756cd0e6f4498742ec495490cb4e5dd382 Mon Sep 17 00:00:00 2001 From: Ray-Not <2sinsincuba@gmail.com> Date: Sat, 20 May 2023 06:54:12 +0500 Subject: [PATCH 61/61] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20editor=20=D0=B8=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FP/.editorconfig | 7 ++++++- FP/checkstyle.xml | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/FP/.editorconfig b/FP/.editorconfig index b43f001..10b0c57 100644 --- a/FP/.editorconfig +++ b/FP/.editorconfig @@ -2,5 +2,10 @@ root = true [*] charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true -[*.java] \ No newline at end of file +[*.java] +indent_style = space +indent_size = 4 diff --git a/FP/checkstyle.xml b/FP/checkstyle.xml index 76dd56a..fad9bdd 100644 --- a/FP/checkstyle.xml +++ b/FP/checkstyle.xml @@ -2,3 +2,11 @@ "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> + + + + + + + +