diff --git a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java index 43b839e..070dfed 100644 --- a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java +++ b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java @@ -1,20 +1,34 @@ package xyz.vallat.louis; +import com.github.wtekiela.opensub4j.response.ListResponse; +import com.github.wtekiela.opensub4j.response.ResponseStatus; +import com.github.wtekiela.opensub4j.response.SubtitleFile; +import com.github.wtekiela.opensub4j.response.SubtitleInfo; import org.apache.commons.cli.*; +import org.apache.xmlrpc.XmlRpcException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xyz.vallat.louis.codes.ExitCodes; import xyz.vallat.louis.database.DBManager; +import xyz.vallat.louis.database.SubtitleLineManager; import xyz.vallat.louis.database.SubtitleManager; import xyz.vallat.louis.discord.DiscordManager; +import xyz.vallat.louis.omdb.objects.Movie; import xyz.vallat.louis.sockets.CommandsClient; import xyz.vallat.louis.sockets.CommandsServer; import xyz.vallat.louis.subtitles.OpenSubtitles; +import xyz.vallat.louis.subtitles.dao.Lang; +import xyz.vallat.louis.subtitles.dao.Subtitle; +import xyz.vallat.louis.subtitles.dao.SubtitleBlock; +import xyz.vallat.louis.subtitles.parser.SubtitleParser; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; public class MoviesQuoteBot { @@ -32,7 +46,7 @@ public class MoviesQuoteBot { options.addOption(Option.builder().longOpt("reimport").build()); } - public static void main(String[] args) throws ParseException { + public static void main(String[] args) throws ParseException, InterruptedException { CommandLine cmd = new DefaultParser().parse(options, args); if (cmd.hasOption("reimport")) reimportAllSubtitleLines(); @@ -94,14 +108,44 @@ public class MoviesQuoteBot { return isInMaintenanceMode; } - private static void reimportAllSubtitleLines() { + private static void reimportAllSubtitleLines() throws InterruptedException { logger.info("Reimporting all subtitle lines."); CommandsClient.checkVersions(); + DBManager.testConnection(); + OpenSubtitles.login(); CommandsClient.setMaintenanceMode(true); - SubtitleManager.getSubtitles().forEach(subtitle -> - logger.debug("[{}] - '{}' in {}.", subtitle.getId(), subtitle.getMovie(), subtitle.getLang().getEnglish()) - ); + SubtitleLineManager.truncateSubtitleLines(); + for (Subtitle subtitle : SubtitleManager.getSubtitles()) { + importSubtitleLines(subtitle); + } CommandsClient.setMaintenanceMode(false); System.exit(0); } + + private static void importSubtitleLines(Subtitle subtitle) throws InterruptedException { + try { + Stream subtitleInfoStream = OpenSubtitles.getSubtitleStreamFromMovie(subtitle.getMovie(), subtitle.getLang().getAlpha3b()); + Optional subtitleInfo = subtitleInfoStream == null ? Optional.empty() : subtitleInfoStream.findFirst(); + if (subtitleInfo.isEmpty()) { + logger.warn("Didn't find anything for the film '{}' in {}.", subtitle.getMovie(), subtitle.getLang().getEnglish()); + } else { + ListResponse subs = OpenSubtitles.downloadSubtitle( + subtitleInfo.get().getSubtitleFileId()); + if (subs.getStatus().equals(ResponseStatus.OK)) { + List blocks = new SubtitleParser().parseSRT( + subs.getData().get(0).getContentAsString(subtitleInfo.get().getEncoding())); + SubtitleLineManager.importSubtitleLines(blocks, subtitle.getLang(), subtitle.getMovie(), null, null); + } else if (subs.getStatus().getCode() == 429) { + logger.warn("Reached requests limit. Retrying in 10 seconds..."); + Thread.sleep(10000); + importSubtitleLines(subtitle); + } else { + logger.error("Server replied with status: '{}' while trying to download subtitle '{}'. Skipping.", + subs.getStatus(), subtitle.getId()); + } + } + } catch (XmlRpcException e) { + logger.error("The OpenSubtitles API had an issue.", e); + } + } } diff --git a/src/main/java/xyz/vallat/louis/commands/Download.java b/src/main/java/xyz/vallat/louis/commands/Download.java index e6aaecf..0d42c17 100644 --- a/src/main/java/xyz/vallat/louis/commands/Download.java +++ b/src/main/java/xyz/vallat/louis/commands/Download.java @@ -56,7 +56,7 @@ public class Download extends Command { Movie movie = OMDBClient.getMovie(cmd.hasOption("i") ? cmd.getOptionValue("i") : String.join(" ", cmd.getOptionValues("t")), cmd.hasOption("i")); - if (movie == null || movie.getId() <= 0) + if (movie == null || movie.getId() < 0) embed.setDescription("We couldn't find any movie with these information. Sorry!"); else if (SubtitleManager.getSubtitlesId(movie, language.getId()) > 0) embed.setDescription("This movie already has already this language imported.") diff --git a/src/main/java/xyz/vallat/louis/database/SubtitleLineManager.java b/src/main/java/xyz/vallat/louis/database/SubtitleLineManager.java index 4138393..02bad8f 100644 --- a/src/main/java/xyz/vallat/louis/database/SubtitleLineManager.java +++ b/src/main/java/xyz/vallat/louis/database/SubtitleLineManager.java @@ -1,19 +1,24 @@ package xyz.vallat.louis.database; +import com.github.wtekiela.opensub4j.response.SubtitleInfo; import discord4j.common.util.Snowflake; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xyz.vallat.louis.codes.ExitCodes; import xyz.vallat.louis.omdb.objects.Movie; +import xyz.vallat.louis.subtitles.OpenSubtitles; import xyz.vallat.louis.subtitles.dao.FilmQuote; import xyz.vallat.louis.subtitles.dao.Lang; import xyz.vallat.louis.subtitles.dao.SubtitleBlock; +import javax.swing.plaf.nimbus.State; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; public final class SubtitleLineManager { @@ -79,29 +84,32 @@ public final class SubtitleLineManager { Snowflake importer, Snowflake importer_guild) { try (Connection connection = DBManager.getConnection()) { connection.setAutoCommit(false); - String querySubtitles = "INSERT INTO subtitles(film_id, language_id, importer_id, importer_guild_id) " + - "VALUES(?, ?, ?, ?);"; - try (PreparedStatement stmt = connection.prepareStatement(querySubtitles, PreparedStatement.RETURN_GENERATED_KEYS)) { - stmt.setInt(1, movie.getId()); - stmt.setInt(2, language.getId()); - stmt.setString(3, importer == null ? null : importer.asString()); - stmt.setString(4, importer_guild == null ? null : importer_guild.asString()); - stmt.executeUpdate(); - stmt.getGeneratedKeys().next(); - int insertedSub = stmt.getGeneratedKeys().getInt(1); - logger.debug("Inserted subtitle with id '{}'.", insertedSub); + int subId = SubtitleManager.getSubtitlesId(movie, language.getId()); + if (subId < 0) { + String querySubtitles = "INSERT INTO subtitles(film_id, language_id, importer_id, importer_guild_id) " + + "VALUES(?, ?, ?, ?);"; + try (PreparedStatement stmt = connection.prepareStatement(querySubtitles, PreparedStatement.RETURN_GENERATED_KEYS)) { + stmt.setInt(1, movie.getId()); + stmt.setInt(2, language.getId()); + stmt.setString(3, importer == null ? null : importer.asString()); + stmt.setString(4, importer_guild == null ? null : importer_guild.asString()); + stmt.executeUpdate(); + stmt.getGeneratedKeys().next(); + subId = stmt.getGeneratedKeys().getInt(1); + logger.debug("Inserted subtitle with id '{}'.", subId); + } + } - String querySubtitleLines = "INSERT INTO subtitle_lines(subtitle_id, dialog_line, time_code) " + - "VALUES(?, ?, ?);"; - for (SubtitleBlock block : subtitleBlocks) { - try (PreparedStatement stmtLines = connection.prepareStatement(querySubtitleLines, PreparedStatement.RETURN_GENERATED_KEYS)) { - stmtLines.setInt(1, insertedSub); - stmtLines.setString(2, block.getDialogue()); - stmtLines.setString(3, block.getTimecode()); - stmtLines.executeUpdate(); - stmtLines.getGeneratedKeys().next(); - logger.debug("Inserted subtitle line with id '{}'.", stmtLines.getGeneratedKeys().getInt(1)); - } + String querySubtitleLines = "INSERT INTO subtitle_lines(subtitle_id, dialog_line, time_code) " + + "VALUES(?, ?, ?);"; + for (SubtitleBlock block : subtitleBlocks) { + try (PreparedStatement stmtLines = connection.prepareStatement(querySubtitleLines, PreparedStatement.RETURN_GENERATED_KEYS)) { + stmtLines.setInt(1, subId); + stmtLines.setString(2, block.getDialogue()); + stmtLines.setString(3, block.getTimecode()); + stmtLines.executeUpdate(); + stmtLines.getGeneratedKeys().next(); + logger.debug("Inserted subtitle line with id '{}'.", stmtLines.getGeneratedKeys().getInt(1)); } } try { @@ -115,6 +123,19 @@ public final class SubtitleLineManager { } } + public static void truncateSubtitleLines() { + logger.warn("Flushing subtitle lines."); + try (Connection connection = DBManager.getConnection()) { + String query = "TRUNCATE subtitle_lines RESTART IDENTITY;"; + try (Statement stmt = connection.createStatement()){ + stmt.executeUpdate(query); + } + } catch (SQLException e) { + logger.error("Cannot connect to database right now: {}", e.getMessage()); + System.exit(ExitCodes.CANNOT_CONNECT_TO_DB.getValue()); + } + } + public static FilmQuote getRandomLine(Lang language, String imdb, String title, String search) { FilmQuote filmQuote = null; try (Connection connection = DBManager.getConnection()) { diff --git a/src/main/java/xyz/vallat/louis/database/SubtitleManager.java b/src/main/java/xyz/vallat/louis/database/SubtitleManager.java index 0b338f2..b60eeff 100644 --- a/src/main/java/xyz/vallat/louis/database/SubtitleManager.java +++ b/src/main/java/xyz/vallat/louis/database/SubtitleManager.java @@ -104,7 +104,7 @@ public final class SubtitleManager { if (stmt.getResultSet().next()) { logger.debug("Found subtitle with id '{}'.", stmt.getResultSet().getInt("id")); return stmt.getResultSet().getInt("id"); - } + } else return -1; } } catch (SQLException e) { logger.error("Cannot connect to database right now: {}", e.getMessage());