From 570eb80f0e1f1143ae2917e1724a6f82c687ecf3 Mon Sep 17 00:00:00 2001 From: Anna Khairillina Date: Sun, 24 Nov 2024 15:17:29 +0500 Subject: [PATCH 1/6] send premiers --- src/main/java/org/oopproject/TelegramBot.java | 98 ++++++++++++++----- 1 file changed, 72 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index 7e58926..cf67f95 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -14,11 +14,11 @@ import static org.oopproject.utils.Replies.getReply; import java.lang.reflect.Type; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.time.LocalDate; +import java.util.*; import java.util.concurrent.*; +import java.util.stream.Collectors; + import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow; import org.telegram.telegrambots.meta.generics.TelegramClient; import org.telegram.telegrambots.meta.api.objects.Update; @@ -98,7 +98,7 @@ public void handleUpdate(Update update) { } } } - + private void loadGenreIndexFromDatabase(long chatId) { String jsonGenreString = database.getGenreIndexesJson(chatId); if (jsonGenreString != null) { @@ -287,7 +287,7 @@ protected String handleYear(String messageText, long chatId) { protected void handleSubscribe(long chatId) { database.updateSubscribe(chatId, true); } - + protected void handleUnsubscribe(long chatId) { database.updateSubscribe(chatId, false); } @@ -317,15 +317,76 @@ protected String handleAge(String messageText, long chatId) { return responseMessage; } + public List getUpcomingMovies() { + try { + // Получаем текущий год и месяц для фильтрации премьеров + LocalDate currentDate = LocalDate.now(); + int currentYear = currentDate.getYear(); + int currentMonth = currentDate.getMonthValue(); + + // Создаем параметры запроса для фильмов, которые были выпущены в текущем месяце + MovieParameters params = new MovieParameters( + "240e7fef369901fb314c80d53d1532d1", // Используйте ваш API ключ TMDb + "PG-13", // Уровень сертификации + "US", // Страна сертификации + false, // Без взрослых фильмов + "ru", // Язык (русский) + 1, // Страница + "2024-11-01", // Начальная дата + currentDate.toString(), // Конечная дата + "release_date.asc", // Сортировка по дате релиза + 0, // Минимальный рейтинг + 10, // Максимальный рейтинг + "", // Жанры + "US", // Страна происхождения + 0, // Минимальное время + currentYear // Год + ); + + // Выполнение запроса + ListDeserializer movieList = tmdbService.findMovie(params); + if (movieList != null && movieList.results != null) { + // Возвращаем первые 5 фильмов + return movieList.results.stream().limit(10).collect(Collectors.toList()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } + + public void startBroadcasting() { - scheduler.scheduleAtFixedRate(()-> { + scheduler.scheduleAtFixedRate(() -> { List subscribedUsers = database.getSubscribedUsers(); + List upcomingMovies = getUpcomingMovies(); // Получаем премьеры + for (Long chatId : subscribedUsers) { - sendMessage(chatId, "Подписчику"); + StringBuilder messageText = new StringBuilder("🎬 Фильмы премьеры:\n"); + + if (upcomingMovies.isEmpty()) { + messageText.append("К сожалению, нет новых фильмов на данный момент."); + } else { + for (int i = 0; i < upcomingMovies.size(); i++) { + FilmDeserializer movie = upcomingMovies.get(i); + messageText.append(i + 1) + .append(". ") + .append(movie.title) + .append("\n") + .append("Дата выхода: ") + .append(movie.release_date) + .append("\n") + .append("Рейтинг: ") + .append(movie.vote_average) + .append("\n\n"); + } + } + sendMessage(chatId, messageText.toString()); // Отправляем сообщение } - }, 0, 1, TimeUnit.MINUTES); + }, 0, 1, TimeUnit.MINUTES); // С интервалом в 1 минуту } - + + private void sendMessage(long chatId, String text) { SendMessage message=SendMessage.builder() .chatId(chatId) @@ -337,7 +398,7 @@ private void sendMessage(long chatId, String text) { e.printStackTrace(); } } - + public String handleSubscription(String messageText, long chatId) { if (isCommand(messageText)) { commandWaiter.put(chatId, NONE); @@ -364,19 +425,4 @@ public String handleSubscription(String messageText, long chatId) { return responseMessage; } -// protected void broadcastMessage(String message) { -// List users = database.getSubscribedUsers(); -// for (Long chatId : users) { -// new SendMessage(chatId, message); -// } -// } -// protected void handleGetAge( long chatId) { -// Integer userAge = database.getUserAge(chatId); -// if (userAge != null) { -// System.out.println("возраст "+ userAge); -// } -// else { -// System.out.println("не нашли возраст"); -// } -// } } \ No newline at end of file From df813d4a777141b28ab16ac2212abad582a46d6e Mon Sep 17 00:00:00 2001 From: Anna Khairillina Date: Sun, 24 Nov 2024 17:40:27 +0500 Subject: [PATCH 2/6] send premiers --- pom.xml | 5 + .../java/org/oopproject/SiteRequests.java | 19 +- src/main/java/org/oopproject/TelegramBot.java | 178 +++++++++++------- .../deserializers/FilmDeserializer.java | 1 + .../deserializers/MovieVideosResponse.java | 11 ++ .../deserializers/VideoDeserializer.java | 16 ++ 6 files changed, 164 insertions(+), 66 deletions(-) create mode 100644 src/main/java/org/oopproject/deserializers/MovieVideosResponse.java create mode 100644 src/main/java/org/oopproject/deserializers/VideoDeserializer.java diff --git a/pom.xml b/pom.xml index 6677579..b24723d 100644 --- a/pom.xml +++ b/pom.xml @@ -101,5 +101,10 @@ 3.1.4 test + + org.eclipse.jetty + jetty-util + 9.4.46.v20220331 + \ No newline at end of file diff --git a/src/main/java/org/oopproject/SiteRequests.java b/src/main/java/org/oopproject/SiteRequests.java index cf9953b..fcf2cdd 100644 --- a/src/main/java/org/oopproject/SiteRequests.java +++ b/src/main/java/org/oopproject/SiteRequests.java @@ -2,12 +2,13 @@ import feign.Param; import feign.RequestLine; -import org.oopproject.deserializers.FilmDeserializer; +import org.oopproject.deserializers.*; import org.oopproject.parameters.MovieParameters; -import org.oopproject.deserializers.AuthDeserializer; -import org.oopproject.deserializers.ListDeserializer; + +import java.util.List; public interface SiteRequests { + @RequestLine("GET /authentication?api_key={api_key}") AuthDeserializer checkAuthStatus(@Param("api_key") String token); @@ -17,6 +18,18 @@ public interface SiteRequests { @RequestLine("GET /movie/{id}?api_key={api_key}") FilmDeserializer getMovieById(@Param("api_key") String token, @Param("id") String id); + @RequestLine("GET /movie/upcoming?api_key={api_key}&language={language}&page={page}") + ListDeserializer findUpcomingMovies(@Param("api_key") String token, + @Param("language") String language, + @Param("page") int page); + + @RequestLine("GET /movie/{id}/videos?api_key={api_key}&language={language}") + MovieVideosResponse getMovieVideos(@Param("api_key") String token, + @Param("id") String movieId, + @Param("language") String language); + + + @RequestLine("GET /discover/movie" + "?api_key={api_key}" + "&certification.lte={certification_lte}" + diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index cf67f95..d5f0d5e 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -2,7 +2,13 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import feign.Feign; +import feign.Logger; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; import org.oopproject.deserializers.ListDeserializer; +import org.oopproject.deserializers.MovieVideosResponse; +import org.oopproject.deserializers.VideoDeserializer; import org.oopproject.utils.CommandWaiter; import org.oopproject.utils.Genres; import org.oopproject.parameters.MovieParameters; @@ -14,7 +20,8 @@ import static org.oopproject.utils.Replies.getReply; import java.lang.reflect.Type; import java.sql.SQLException; -import java.time.LocalDate; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; @@ -44,8 +51,8 @@ public class TelegramBot implements LongPollingSingleThreadUpdateConsumer { public TelegramBot(String botToken) throws SQLException { telegramClient = new OkHttpTelegramClient(botToken); - startBroadcasting(); - } + BroadcastingService broadcastingService = new BroadcastingService(); // Initialize BroadcastingService + broadcastingService.startBroadcasting(); } @Override public void consume(Update update) { @@ -317,76 +324,121 @@ protected String handleAge(String messageText, long chatId) { return responseMessage; } - public List getUpcomingMovies() { - try { - // Получаем текущий год и месяц для фильтрации премьеров - LocalDate currentDate = LocalDate.now(); - int currentYear = currentDate.getYear(); - int currentMonth = currentDate.getMonthValue(); - - // Создаем параметры запроса для фильмов, которые были выпущены в текущем месяце - MovieParameters params = new MovieParameters( - "240e7fef369901fb314c80d53d1532d1", // Используйте ваш API ключ TMDb - "PG-13", // Уровень сертификации - "US", // Страна сертификации - false, // Без взрослых фильмов - "ru", // Язык (русский) - 1, // Страница - "2024-11-01", // Начальная дата - currentDate.toString(), // Конечная дата - "release_date.asc", // Сортировка по дате релиза - 0, // Минимальный рейтинг - 10, // Максимальный рейтинг - "", // Жанры - "US", // Страна происхождения - 0, // Минимальное время - currentYear // Год - ); - - // Выполнение запроса - ListDeserializer movieList = tmdbService.findMovie(params); - if (movieList != null && movieList.results != null) { - // Возвращаем первые 5 фильмов - return movieList.results.stream().limit(10).collect(Collectors.toList()); + public class MovieService { + + private SiteRequests siteRequests; + private int currentPage; + + public MovieService() { + siteRequests = Feign.builder() + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logLevel(Logger.Level.FULL) + .target(SiteRequests.class, "https://api.themoviedb.org/3"); + this.currentPage = 1; + } + + private boolean isUpcoming(String releaseDate) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date release = sdf.parse(releaseDate); + Date now = new Date(); + return release.after(now); + } catch (ParseException e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); + return false; + } + public List getUpcomingMovies() { + try { + ListDeserializer upcomingMovies = siteRequests.findUpcomingMovies( + "240e7fef369901fb314c80d53d1532d1", + "ru", + currentPage + ); + + if (upcomingMovies != null && upcomingMovies.results != null) { + List resultList = upcomingMovies.results.stream() + .filter(movie -> isUpcoming(movie.release_date)) + .limit(10) // Ограничиваем до 10 фильмов + .collect(Collectors.toList()); + for (FilmDeserializer movie : resultList) { + MovieVideosResponse videoResponse = siteRequests.getMovieVideos( + "240e7fef369901fb314c80d53d1532d1", + String.valueOf(movie.id), + "ru" + ); + + if (videoResponse != null && videoResponse.results != null && !videoResponse.results.isEmpty()) { + // Найдем первый трейлер (если он есть) + VideoDeserializer trailer = videoResponse.results.stream() + .filter(v -> v.site.equals("YouTube")) + .findFirst() + .orElse(null); + + if (trailer != null) { + // Формируем ссылку на трейлер + movie.trailerUrl = "https://www.youtube.com/watch?v=" + trailer.key; + } + } + } + currentPage++; + return resultList; + } + } catch (Exception e) { + e.printStackTrace(); + } + return Collections.emptyList(); } - return Collections.emptyList(); } + public class BroadcastingService { + + private MovieService movieService; + + public BroadcastingService() { + this.movieService = new MovieService(); + } - public void startBroadcasting() { - scheduler.scheduleAtFixedRate(() -> { - List subscribedUsers = database.getSubscribedUsers(); - List upcomingMovies = getUpcomingMovies(); // Получаем премьеры - - for (Long chatId : subscribedUsers) { - StringBuilder messageText = new StringBuilder("🎬 Фильмы премьеры:\n"); - - if (upcomingMovies.isEmpty()) { - messageText.append("К сожалению, нет новых фильмов на данный момент."); - } else { - for (int i = 0; i < upcomingMovies.size(); i++) { - FilmDeserializer movie = upcomingMovies.get(i); - messageText.append(i + 1) - .append(". ") - .append(movie.title) - .append("\n") - .append("Дата выхода: ") - .append(movie.release_date) - .append("\n") - .append("Рейтинг: ") - .append(movie.vote_average) - .append("\n\n"); + public void startBroadcasting() { + scheduler.scheduleAtFixedRate(() -> { + List subscribedUsers = database.getSubscribedUsers(); + List upcomingMovies = movieService.getUpcomingMovies(); + + for (Long chatId : subscribedUsers) { + StringBuilder messageText = new StringBuilder("🎬 Фильмы, которые скоро выйдут:\n"); + + if (upcomingMovies.isEmpty()) { + messageText.append("К сожалению, нет новых фильмов на данный момент."); + } else { + for (int i = 0; i < upcomingMovies.size(); i++) { + FilmDeserializer movie = upcomingMovies.get(i); + messageText.append(i + 1) + .append(". ") + .append(movie.title) + .append("\n") + .append("Дата выхода: ") + .append(movie.release_date) + .append("\n") + .append("Описание: ") + .append(movie.overview != null && !movie.overview.isEmpty() ? movie.overview : "Нет описания") + .append("\n"); + if (movie.trailerUrl != null) { + messageText.append("Ссылка на трейлер: ").append(movie.trailerUrl).append("\n"); + } + + messageText.append("\n"); + } } + sendMessage(chatId, messageText.toString()); } - sendMessage(chatId, messageText.toString()); // Отправляем сообщение - } - }, 0, 1, TimeUnit.MINUTES); // С интервалом в 1 минуту + }, 0, 1, TimeUnit.MINUTES); + } } + + private void sendMessage(long chatId, String text) { SendMessage message=SendMessage.builder() .chatId(chatId) diff --git a/src/main/java/org/oopproject/deserializers/FilmDeserializer.java b/src/main/java/org/oopproject/deserializers/FilmDeserializer.java index b169207..8581e60 100644 --- a/src/main/java/org/oopproject/deserializers/FilmDeserializer.java +++ b/src/main/java/org/oopproject/deserializers/FilmDeserializer.java @@ -27,6 +27,7 @@ public class FilmDeserializer { public boolean video; public double vote_average; public double vote_count; + public String trailerUrl; // public boolean belongs_to_collection; // public List production_companies; // public List production_countries; diff --git a/src/main/java/org/oopproject/deserializers/MovieVideosResponse.java b/src/main/java/org/oopproject/deserializers/MovieVideosResponse.java new file mode 100644 index 0000000..26c42f0 --- /dev/null +++ b/src/main/java/org/oopproject/deserializers/MovieVideosResponse.java @@ -0,0 +1,11 @@ +package org.oopproject.deserializers; + +import com.google.gson.annotations.SerializedName; +import java.util.List; + +public class MovieVideosResponse { + @SerializedName("results") + public List results; // Список видео + + // Конструкторы и методы, если нужно +} diff --git a/src/main/java/org/oopproject/deserializers/VideoDeserializer.java b/src/main/java/org/oopproject/deserializers/VideoDeserializer.java new file mode 100644 index 0000000..151e725 --- /dev/null +++ b/src/main/java/org/oopproject/deserializers/VideoDeserializer.java @@ -0,0 +1,16 @@ +package org.oopproject.deserializers; + +import com.google.gson.annotations.SerializedName; + +public class VideoDeserializer { + @SerializedName("key") + public String key; // Ключ видео, который будет использоваться для ссылки + + @SerializedName("name") + public String name; // Название видео (например, "Трейлер") + + @SerializedName("site") + public String site; // Платформа видео (например, "YouTube") + + // Конструкторы и методы, если нужно +} From 7d547fd71c1907ce97a3d49e79dd279f3b611c00 Mon Sep 17 00:00:00 2001 From: Anna Khairillina Date: Sat, 30 Nov 2024 23:10:10 +0500 Subject: [PATCH 3/6] added getting age from database --- src/main/java/org/oopproject/TelegramBot.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index d5f0d5e..80a57c7 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -63,6 +63,7 @@ public void handleUpdate(Update update) { if (update.hasMessage() && update.getMessage().hasText()) { long chatId = update.getMessage().getChatId(); database.insertChatId(chatId); + Integer userAge=getUserAge(chatId); loadGenreIndexFromDatabase(chatId); loadYearIndexFromDatabase(chatId); @@ -324,6 +325,10 @@ protected String handleAge(String messageText, long chatId) { return responseMessage; } + public Integer getUserAge(long chatId) { + return database.getUserAge(chatId); + } + public class MovieService { private SiteRequests siteRequests; From 6f829a8b2239f0338a55f6b8263d99dc5d9325c3 Mon Sep 17 00:00:00 2001 From: aqerd <2195486@gmail.com> Date: Sun, 1 Dec 2024 21:02:49 +0500 Subject: [PATCH 4/6] User's age handled --- src/main/java/org/oopproject/Database.java | 1 - src/main/java/org/oopproject/TelegramBot.java | 11 +++---- .../java/org/oopproject/utils/AgeRating.java | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/oopproject/utils/AgeRating.java diff --git a/src/main/java/org/oopproject/Database.java b/src/main/java/org/oopproject/Database.java index 066dbf0..cbc93ad 100644 --- a/src/main/java/org/oopproject/Database.java +++ b/src/main/java/org/oopproject/Database.java @@ -60,7 +60,6 @@ public Integer getUserAge(long chatId) { e.printStackTrace(); } return null; - } public void updateGenreIndexesJson(long chatId, String genreIndexesJson) { diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index 80a57c7..0ea7399 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -14,6 +14,8 @@ import org.oopproject.parameters.MovieParameters; import org.oopproject.parameters.ParametersBuilder; import org.oopproject.deserializers.FilmDeserializer; + +import static org.oopproject.utils.AgeRating.getRatingForAge; import static org.oopproject.utils.CommandWaiter.*; import static org.oopproject.utils.Config.tmdbService; import static org.oopproject.utils.Validators.isCommand; @@ -251,7 +253,7 @@ protected String handleYear(String messageText, long chatId) { try { int userYear = Integer.parseInt(messageText); int currentYear = java.time.Year.now().getValue(); - + String userRating = getRatingForAge(getUserAge(chatId)); if (userYear < 1900 || userYear > currentYear) { responseMessage = "Пожалуйста, введите год в диапазоне от 1900 до " + currentYear; return responseMessage; @@ -259,8 +261,7 @@ protected String handleYear(String messageText, long chatId) { MovieParameters params = new ParametersBuilder() .withYear(userYear) - .withCertificationLte("PG-13") - .withCertificationCountry("US") + .withCertificationLte(userRating) .build(); ListDeserializer moviesByYear = tmdbService.findMovie(params); @@ -441,9 +442,6 @@ public void startBroadcasting() { } } - - - private void sendMessage(long chatId, String text) { SendMessage message=SendMessage.builder() .chatId(chatId) @@ -481,5 +479,4 @@ public String handleSubscription(String messageText, long chatId) { } return responseMessage; } - } \ No newline at end of file diff --git a/src/main/java/org/oopproject/utils/AgeRating.java b/src/main/java/org/oopproject/utils/AgeRating.java new file mode 100644 index 0000000..f606345 --- /dev/null +++ b/src/main/java/org/oopproject/utils/AgeRating.java @@ -0,0 +1,32 @@ +package org.oopproject.utils; + +public enum AgeRating { + GENERAL("G", 0, 5), + PARENTAL_GUIDANCE("PG", 6, 11), + WITH_PARENTS_STRONGLY("PG-13", 12, 15), + RESTRICTED("R", 16, 17), + ADULTS("NC-17", 18, 120); + + private final String rating; + private final int minAge; + private final int maxAge; + + AgeRating(String rating, int minAge, int maxAge) { + this.rating = rating; + this.minAge = minAge; + this.maxAge = maxAge; + } + + public static String getRatingForAge(int age) { + for (AgeRating rating : values()) { + if (age >= rating.minAge && age <= rating.maxAge) { + return rating.rating; + } + } + return null; + } + + public String getRating() { + return rating; + } +} \ No newline at end of file From 65329772265b938ae275eb40d834a9d62dc4e112 Mon Sep 17 00:00:00 2001 From: aqerd <2195486@gmail.com> Date: Sun, 1 Dec 2024 21:10:28 +0500 Subject: [PATCH 5/6] User's age handled for genre --- src/main/java/org/oopproject/TelegramBot.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index 0ea7399..5852d29 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -199,11 +199,11 @@ protected String handleGenre(String messageText, long chatId) { try { String genreId = Genres.valueOf(messageText.toUpperCase()).genreId; + String userRating = getRatingForAge(getUserAge(chatId)); MovieParameters params = new ParametersBuilder() .withGenres(genreId) - .withCertificationLte("PG-13") - .withCertificationCountry("US") + .withCertificationLte(userRating) .build(); ListDeserializer moviesByGenre = tmdbService.findMovie(params); @@ -222,7 +222,6 @@ protected String handleGenre(String messageText, long chatId) { updateGenreIndexInDatabase(chatId); - responseMessage = movieListBuilder.toString(); } else { @@ -242,7 +241,6 @@ private void updateYearIndexInDatabase(long chatId) { } protected String handleYear(String messageText, long chatId) { - if (isCommand(messageText)) { commandWaiter.put(chatId, NONE); return handleCommands(messageText, chatId); From 5d5f6c63dab537f7ae15e0e9ae492c23c2b3ad31 Mon Sep 17 00:00:00 2001 From: Anna Khairillina Date: Sun, 1 Dec 2024 23:38:46 +0500 Subject: [PATCH 6/6] new package for sevices --- src/main/java/org/oopproject/TelegramBot.java | 125 +----------------- .../services/BroadcastingService.java | 72 ++++++++++ .../org/oopproject/services/MovieService.java | 83 ++++++++++++ 3 files changed, 158 insertions(+), 122 deletions(-) create mode 100644 src/main/java/org/oopproject/services/BroadcastingService.java create mode 100644 src/main/java/org/oopproject/services/MovieService.java diff --git a/src/main/java/org/oopproject/TelegramBot.java b/src/main/java/org/oopproject/TelegramBot.java index 5852d29..9cb8ecb 100644 --- a/src/main/java/org/oopproject/TelegramBot.java +++ b/src/main/java/org/oopproject/TelegramBot.java @@ -2,13 +2,8 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import feign.Feign; -import feign.Logger; -import feign.gson.GsonDecoder; -import feign.gson.GsonEncoder; import org.oopproject.deserializers.ListDeserializer; -import org.oopproject.deserializers.MovieVideosResponse; -import org.oopproject.deserializers.VideoDeserializer; +import org.oopproject.services.BroadcastingService; import org.oopproject.utils.CommandWaiter; import org.oopproject.utils.Genres; import org.oopproject.parameters.MovieParameters; @@ -21,12 +16,8 @@ import static org.oopproject.utils.Validators.isCommand; import static org.oopproject.utils.Replies.getReply; import java.lang.reflect.Type; -import java.sql.SQLException; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; -import java.util.stream.Collectors; import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow; import org.telegram.telegrambots.meta.generics.TelegramClient; @@ -51,9 +42,9 @@ public class TelegramBot implements LongPollingSingleThreadUpdateConsumer { private final HashMap genreMovieIndexMap = new HashMap<>(); private final Map commandWaiter = new ConcurrentHashMap<>(); - public TelegramBot(String botToken) throws SQLException { + public TelegramBot(String botToken) { telegramClient = new OkHttpTelegramClient(botToken); - BroadcastingService broadcastingService = new BroadcastingService(); // Initialize BroadcastingService + BroadcastingService broadcastingService = new BroadcastingService(database, telegramClient); broadcastingService.startBroadcasting(); } @Override @@ -328,117 +319,7 @@ public Integer getUserAge(long chatId) { return database.getUserAge(chatId); } - public class MovieService { - private SiteRequests siteRequests; - private int currentPage; - - public MovieService() { - siteRequests = Feign.builder() - .encoder(new GsonEncoder()) - .decoder(new GsonDecoder()) - .logLevel(Logger.Level.FULL) - .target(SiteRequests.class, "https://api.themoviedb.org/3"); - this.currentPage = 1; - } - - private boolean isUpcoming(String releaseDate) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - Date release = sdf.parse(releaseDate); - Date now = new Date(); - return release.after(now); - } catch (ParseException e) { - e.printStackTrace(); - } - return false; - } - public List getUpcomingMovies() { - try { - ListDeserializer upcomingMovies = siteRequests.findUpcomingMovies( - "240e7fef369901fb314c80d53d1532d1", - "ru", - currentPage - ); - - if (upcomingMovies != null && upcomingMovies.results != null) { - List resultList = upcomingMovies.results.stream() - .filter(movie -> isUpcoming(movie.release_date)) - .limit(10) // Ограничиваем до 10 фильмов - .collect(Collectors.toList()); - for (FilmDeserializer movie : resultList) { - MovieVideosResponse videoResponse = siteRequests.getMovieVideos( - "240e7fef369901fb314c80d53d1532d1", - String.valueOf(movie.id), - "ru" - ); - - if (videoResponse != null && videoResponse.results != null && !videoResponse.results.isEmpty()) { - // Найдем первый трейлер (если он есть) - VideoDeserializer trailer = videoResponse.results.stream() - .filter(v -> v.site.equals("YouTube")) - .findFirst() - .orElse(null); - - if (trailer != null) { - // Формируем ссылку на трейлер - movie.trailerUrl = "https://www.youtube.com/watch?v=" + trailer.key; - } - } - } - currentPage++; - return resultList; - } - } catch (Exception e) { - e.printStackTrace(); - } - return Collections.emptyList(); - } - } - - public class BroadcastingService { - - private MovieService movieService; - - public BroadcastingService() { - this.movieService = new MovieService(); - } - - public void startBroadcasting() { - scheduler.scheduleAtFixedRate(() -> { - List subscribedUsers = database.getSubscribedUsers(); - List upcomingMovies = movieService.getUpcomingMovies(); - - for (Long chatId : subscribedUsers) { - StringBuilder messageText = new StringBuilder("🎬 Фильмы, которые скоро выйдут:\n"); - - if (upcomingMovies.isEmpty()) { - messageText.append("К сожалению, нет новых фильмов на данный момент."); - } else { - for (int i = 0; i < upcomingMovies.size(); i++) { - FilmDeserializer movie = upcomingMovies.get(i); - messageText.append(i + 1) - .append(". ") - .append(movie.title) - .append("\n") - .append("Дата выхода: ") - .append(movie.release_date) - .append("\n") - .append("Описание: ") - .append(movie.overview != null && !movie.overview.isEmpty() ? movie.overview : "Нет описания") - .append("\n"); - if (movie.trailerUrl != null) { - messageText.append("Ссылка на трейлер: ").append(movie.trailerUrl).append("\n"); - } - - messageText.append("\n"); - } - } - sendMessage(chatId, messageText.toString()); - } - }, 0, 1, TimeUnit.MINUTES); - } - } private void sendMessage(long chatId, String text) { SendMessage message=SendMessage.builder() diff --git a/src/main/java/org/oopproject/services/BroadcastingService.java b/src/main/java/org/oopproject/services/BroadcastingService.java new file mode 100644 index 0000000..2b68fa3 --- /dev/null +++ b/src/main/java/org/oopproject/services/BroadcastingService.java @@ -0,0 +1,72 @@ +package org.oopproject.services; + +import org.oopproject.Database; +import org.oopproject.deserializers.FilmDeserializer; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.exceptions.TelegramApiException; +import org.telegram.telegrambots.meta.generics.TelegramClient; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class BroadcastingService { + private final Database database; + private final MovieService movieService; + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + private final TelegramClient telegramClient; + + public BroadcastingService(Database database, TelegramClient telegramClient) { + this.database = database; + this.telegramClient = telegramClient; + this.movieService = new MovieService(); + } + + public void startBroadcasting() { + scheduler.scheduleAtFixedRate(() -> { + List subscribedUsers = database.getSubscribedUsers(); + List upcomingMovies = movieService.getUpcomingMovies(); + + for (Long chatId : subscribedUsers) { + StringBuilder messageText = new StringBuilder("🎬 Фильмы, которые скоро выйдут:\n"); + + if (upcomingMovies.isEmpty()) { + messageText.append("К сожалению, нет новых фильмов на данный момент."); + } else { + for (int i = 0; i < upcomingMovies.size(); i++) { + FilmDeserializer movie = upcomingMovies.get(i); + messageText.append(i + 1) + .append(". ") + .append(movie.title) + .append("\n") + .append("Дата выхода: ") + .append(movie.release_date) + .append("\n") + .append("Описание: ") + .append(movie.overview != null && !movie.overview.isEmpty() ? movie.overview : "Нет описания") + .append("\n"); + if (movie.trailerUrl != null) { + messageText.append("Ссылка на трейлер: ").append(movie.trailerUrl).append("\n"); + } + + messageText.append("\n"); + } + } + sendMessage(chatId, messageText.toString()); + } + }, 0, 3, TimeUnit.DAYS); + } + + private void sendMessage(long chatId, String text) { + SendMessage message = SendMessage.builder() + .chatId(chatId) + .text(text) + .build(); + try { + telegramClient.execute(message); + } catch (TelegramApiException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/org/oopproject/services/MovieService.java b/src/main/java/org/oopproject/services/MovieService.java new file mode 100644 index 0000000..682d6d1 --- /dev/null +++ b/src/main/java/org/oopproject/services/MovieService.java @@ -0,0 +1,83 @@ +package org.oopproject.services; + +import feign.Feign; +import feign.Logger; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import org.oopproject.SiteRequests; +import org.oopproject.deserializers.FilmDeserializer; +import org.oopproject.deserializers.ListDeserializer; +import org.oopproject.deserializers.MovieVideosResponse; +import org.oopproject.deserializers.VideoDeserializer; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +public class MovieService { + private SiteRequests siteRequests; + private int currentPage; + + public MovieService() { + siteRequests = Feign.builder() + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logLevel(Logger.Level.FULL) + .target(SiteRequests.class, "https://api.themoviedb.org/3"); + this.currentPage = 1; + } + + private boolean isUpcoming(String releaseDate) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date release = sdf.parse(releaseDate); + Date now = new Date(); + return release.after(now); + } catch (ParseException e) { + e.printStackTrace(); + } + return false; + } + public List getUpcomingMovies() { + try { + ListDeserializer upcomingMovies = siteRequests.findUpcomingMovies( + "240e7fef369901fb314c80d53d1532d1", + "ru", + currentPage + ); + + if (upcomingMovies != null && upcomingMovies.results != null) { + List resultList = upcomingMovies.results.stream() + .filter(movie -> isUpcoming(movie.release_date)) + .limit(10) // Ограничиваем до 10 фильмов + .collect(Collectors.toList()); + for (FilmDeserializer movie : resultList) { + MovieVideosResponse videoResponse = siteRequests.getMovieVideos( + "240e7fef369901fb314c80d53d1532d1", + String.valueOf(movie.id), + "ru" + ); + + if (videoResponse != null && videoResponse.results != null && !videoResponse.results.isEmpty()) { + VideoDeserializer trailer = videoResponse.results.stream() + .filter(v -> v.site.equals("YouTube")) + .findFirst() + .orElse(null); + + if (trailer != null) { + movie.trailerUrl = "https://www.youtube.com/watch?v=" + trailer.key; + } + } + } + currentPage++; + return resultList; + } + } catch (Exception e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } +}