Basic POC for importing subtitles.
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
f0b757060a
commit
d645ccb711
@ -4,6 +4,7 @@ import com.github.wtekiela.opensub4j.response.ListResponse;
|
|||||||
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
||||||
import com.github.wtekiela.opensub4j.response.SubtitleInfo;
|
import com.github.wtekiela.opensub4j.response.SubtitleInfo;
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||||
|
import discord4j.core.object.reaction.ReactionEmoji;
|
||||||
import discord4j.core.spec.EmbedCreateSpec;
|
import discord4j.core.spec.EmbedCreateSpec;
|
||||||
import discord4j.rest.util.Color;
|
import discord4j.rest.util.Color;
|
||||||
import org.apache.xmlrpc.XmlRpcException;
|
import org.apache.xmlrpc.XmlRpcException;
|
||||||
@ -16,6 +17,7 @@ import xyz.vallat.louis.subtitles.OpenSubtitles;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -25,6 +27,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public abstract class Command {
|
public abstract class Command {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ListLangMovie.class.getCanonicalName());
|
private static final Logger logger = LoggerFactory.getLogger(ListLangMovie.class.getCanonicalName());
|
||||||
|
protected static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛");
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
protected final String description;
|
protected final String description;
|
||||||
@ -72,7 +75,7 @@ public abstract class Command {
|
|||||||
protected Mono<Void> badArgument(MessageCreateEvent event, String arg) {
|
protected Mono<Void> badArgument(MessageCreateEvent event, String arg) {
|
||||||
return event.getMessage().getChannel()
|
return event.getMessage().getChannel()
|
||||||
.flatMap(channel ->
|
.flatMap(channel ->
|
||||||
channel.createMessage("Error, this argument isn't recognized: '" + arg + "'.\n" + getUsage()))
|
channel.createMessage("Error, this argument isn't recognized: '" + arg + "'.\n Usage: " + getUsage()))
|
||||||
.then();
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,4 +133,8 @@ public abstract class Command {
|
|||||||
+ " - " + subtitleInfo.getLanguage())
|
+ " - " + subtitleInfo.getLanguage())
|
||||||
.limit(20);
|
.limit(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<String> getArguments(MessageCreateEvent event) {
|
||||||
|
return List.of(event.getMessage().getContent().substring(Math.min(name.length() + 1, name.length())).split(" "));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,43 +4,52 @@ import com.github.wtekiela.opensub4j.response.ListResponse;
|
|||||||
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
||||||
import com.github.wtekiela.opensub4j.response.SubtitleFile;
|
import com.github.wtekiela.opensub4j.response.SubtitleFile;
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||||
|
import discord4j.rest.util.Color;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.xmlrpc.XmlRpcException;
|
import org.apache.xmlrpc.XmlRpcException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import xyz.vallat.louis.database.SubtitleLineManager;
|
||||||
import xyz.vallat.louis.subtitles.OpenSubtitles;
|
import xyz.vallat.louis.subtitles.OpenSubtitles;
|
||||||
import xyz.vallat.louis.subtitles.parser.SubtitleParser;
|
import xyz.vallat.louis.subtitles.parser.SubtitleParser;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Download extends Command {
|
public class Download extends Command {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Download.class.getCanonicalName());
|
||||||
|
|
||||||
public Download(String name) {
|
public Download(String name) {
|
||||||
super(name, "Download a subtitle.", " subtitleId", 1, 1);
|
super(name, "Download a subtitle.", name + " subtitleId", 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> execute(MessageCreateEvent event) {
|
public Mono<Void> execute(MessageCreateEvent event) {
|
||||||
String[] args = event.getMessage().getContent().split(" ");
|
List<String> args = getArguments(event);
|
||||||
if (args.length < minArgs || (args.length >= 1 && !StringUtils.isNumeric(args[1])))
|
if (args.isEmpty()) return notEnoughArguments(event);
|
||||||
return event.getMessage().getChannel()
|
else if (!StringUtils.isNumeric(args.get(0))) return badArgument(event, args.get(0));
|
||||||
.flatMap(messageChannel -> messageChannel.createMessage("Error: malformed arguments. " +
|
return event.getMessage().getChannel().flatMap(channel -> event.getMessage().addReaction(WAITING).then(
|
||||||
"Usage:" + usage)).then();
|
channel.createEmbed(embed -> {
|
||||||
|
embed.setTitle("Importation").setColor(Color.RED);
|
||||||
try {
|
try {
|
||||||
ListResponse<SubtitleFile> subs = OpenSubtitles.downloadSubtitle(Integer.parseInt(args[1]));
|
ListResponse<SubtitleFile> subs = OpenSubtitles.downloadSubtitle(Integer.parseInt(args.get(0)));
|
||||||
if (subs.getStatus().getCode() == ResponseStatus.OK.getCode()) {
|
if (subs.getStatus().getCode() == ResponseStatus.OK.getCode()) {
|
||||||
return event.getMessage().getChannel()
|
SubtitleLineManager.importSubtitleLines(
|
||||||
.flatMap(messageChannel ->
|
new SubtitleParser().parseSRT(
|
||||||
{
|
subs.getData().get(0).getContentAsString("cp1252")));
|
||||||
String var = subs.getData().get(0).getContentAsString("cp1252");
|
embed.setColor(Color.MEDIUM_SEA_GREEN).setDescription("Everything went well.");
|
||||||
SubtitleParser subtitleParser = new SubtitleParser();
|
} else {
|
||||||
subtitleParser.parseSRT(var);
|
logger.error("Could not download subtitle '{}': {}", args.get(0), subs.getStatus());
|
||||||
return messageChannel.createMessage("Imported.");
|
embed.setDescription("An error occurred. Please contact my administrator.");
|
||||||
}
|
}
|
||||||
)
|
} catch (XmlRpcException e) {
|
||||||
.then();
|
logger.error("An error occurred while fetching the data from opensubtitles: {}", e.getMessage());
|
||||||
} else
|
embed.setDescription("An error occurred, please contact my administrator.");
|
||||||
return event.getMessage().getChannel().flatMap(channel -> channel.createMessage("An error occurred.")).then();
|
|
||||||
} catch (XmlRpcException ignored) {
|
|
||||||
return event.getMessage().getChannel().flatMap(messageChannel -> messageChannel.createMessage("Error.")).then();
|
|
||||||
}
|
}
|
||||||
|
embed.setTimestamp(Instant.now());
|
||||||
|
}
|
||||||
|
))).then(event.getMessage().removeSelfReaction(WAITING)).then();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package xyz.vallat.louis.commands;
|
package xyz.vallat.louis.commands;
|
||||||
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||||
import discord4j.core.object.reaction.ReactionEmoji;
|
|
||||||
import discord4j.rest.util.Color;
|
import discord4j.rest.util.Color;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -13,16 +12,15 @@ import java.util.List;
|
|||||||
public class ListLangMovie extends Command {
|
public class ListLangMovie extends Command {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ListLangMovie.class.getCanonicalName());
|
private static final Logger logger = LoggerFactory.getLogger(ListLangMovie.class.getCanonicalName());
|
||||||
private static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛");
|
|
||||||
|
|
||||||
public ListLangMovie(String name) {
|
public ListLangMovie(String name) {
|
||||||
super(name, "List all languages attached to a film title or an IMDB Identifier.",
|
super(name, "List all languages attached to a film title or an IMDB Identifier.",
|
||||||
name + " imdb|title value", 3, 3);
|
name + " imdb|title value", 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> execute(MessageCreateEvent event) {
|
public Mono<Void> execute(MessageCreateEvent event) {
|
||||||
List<String> arguments = List.of(event.getMessage().getContent().split(" "));
|
List<String> arguments = getArguments(event);
|
||||||
if (arguments.size() < minArgs) return notEnoughArguments(event);
|
if (arguments.size() < minArgs) return notEnoughArguments(event);
|
||||||
else if (!arguments.get(1).equalsIgnoreCase("imdb") &&
|
else if (!arguments.get(1).equalsIgnoreCase("imdb") &&
|
||||||
!arguments.get(1).equalsIgnoreCase("title"))
|
!arguments.get(1).equalsIgnoreCase("title"))
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
package xyz.vallat.louis.commands;
|
|
||||||
|
|
||||||
import com.github.wtekiela.opensub4j.response.ListResponse;
|
|
||||||
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
|
||||||
import com.github.wtekiela.opensub4j.response.SubtitleInfo;
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import discord4j.core.object.entity.channel.MessageChannel;
|
|
||||||
import discord4j.core.object.reaction.ReactionEmoji;
|
|
||||||
import discord4j.rest.util.Color;
|
|
||||||
import org.apache.xmlrpc.XmlRpcException;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
import xyz.vallat.louis.subtitles.OpenSubtitles;
|
|
||||||
|
|
||||||
public class ListLangMovieImdb extends Command {
|
|
||||||
|
|
||||||
private static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛");
|
|
||||||
|
|
||||||
public ListLangMovieImdb(String name) {
|
|
||||||
super(name, "List all languages attached to a film using its IMDB Identifier.", name + " IMDB_ID", 1, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> execute(MessageCreateEvent event) {
|
|
||||||
String arg = event.getMessage().getContent().substring(name.length() + 1);
|
|
||||||
if (arg.isBlank()) return notEnoughArguments(event);
|
|
||||||
return event.getMessage().getChannel()
|
|
||||||
.flatMap(channel -> {
|
|
||||||
if (OpenSubtitles.isLoggedIn()) {
|
|
||||||
return event.getMessage().addReaction(WAITING)
|
|
||||||
.then(event.getMessage().getChannel().flatMap(messageChannel ->
|
|
||||||
searchAndShowFilms(arg, channel, messageChannel)))
|
|
||||||
.then(event.getMessage().removeSelfReaction(WAITING))
|
|
||||||
.then();
|
|
||||||
} else return channel.createMessage("I cannot search for subtitle languages right now. Sorry.");
|
|
||||||
})
|
|
||||||
.then();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: ADD MOVIE TITLE
|
|
||||||
private Mono<? extends Message> searchAndShowFilms(String arg, MessageChannel channel, MessageChannel messageChannel) {
|
|
||||||
try {
|
|
||||||
ListResponse<SubtitleInfo> subtitles = OpenSubtitles.searchSubtitles("", arg);
|
|
||||||
if (subtitles.getStatus().getCode() == ResponseStatus.OK.getCode()) {
|
|
||||||
return messageChannel.createEmbed(
|
|
||||||
embed -> {
|
|
||||||
embed.setTitle("Results")
|
|
||||||
.setDescription("Found " + subtitles.getData().size() + " results.")
|
|
||||||
.setColor(Color.BISMARK);
|
|
||||||
if (!subtitles.getData().isEmpty()) {
|
|
||||||
StringBuilder s = new StringBuilder();
|
|
||||||
for (SubtitleInfo info : subtitles.getData().subList(0, Math.min(10, subtitles.getData().size())))
|
|
||||||
s.append(info.getSubtitleFileId()).append(" - ").append(info.getLanguage()).append("\n");
|
|
||||||
embed.addField("Languages found", s.toString(), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (subtitles.getStatus().getCode() == ResponseStatus.INVALID_PARAMETERS.getCode()) {
|
|
||||||
return messageChannel.createMessage("It looks like it is an invalid IMDB identifier.");
|
|
||||||
} else {
|
|
||||||
return messageChannel.createMessage("An error happened while fetching the results. " +
|
|
||||||
"Try again later, or contact my administrator." + subtitles.getStatus());
|
|
||||||
}
|
|
||||||
} catch (XmlRpcException e) {
|
|
||||||
return channel.createMessage("It seems like OpenSubtitles had a stroke.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package xyz.vallat.louis.commands;
|
|
||||||
|
|
||||||
import com.github.wtekiela.opensub4j.response.ListResponse;
|
|
||||||
import com.github.wtekiela.opensub4j.response.MovieInfo;
|
|
||||||
import com.github.wtekiela.opensub4j.response.ResponseStatus;
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import discord4j.core.object.entity.channel.MessageChannel;
|
|
||||||
import discord4j.core.object.reaction.ReactionEmoji;
|
|
||||||
import discord4j.rest.util.Color;
|
|
||||||
import org.apache.xmlrpc.XmlRpcException;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
import xyz.vallat.louis.subtitles.OpenSubtitles;
|
|
||||||
|
|
||||||
public class SearchTitle extends Command {
|
|
||||||
|
|
||||||
private static final ReactionEmoji WAITING = ReactionEmoji.unicode("⌛");
|
|
||||||
private static final String FORMAT = "%1$-7s - %2$s\n";
|
|
||||||
|
|
||||||
public SearchTitle(String name) {
|
|
||||||
super(name, "A command to search some subtitles.", name + " <name>", 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> execute(MessageCreateEvent event) {
|
|
||||||
String arg = event.getMessage().getContent().substring(name.length() + 1);
|
|
||||||
if (arg.replace(" ", "").length() == 0)
|
|
||||||
return notEnoughArguments(event);
|
|
||||||
return event.getMessage().getChannel()
|
|
||||||
.flatMap(channel -> {
|
|
||||||
if (OpenSubtitles.isLoggedIn()) {
|
|
||||||
return event.getMessage().addReaction(WAITING)
|
|
||||||
.then(event.getMessage().getChannel().flatMap(messageChannel ->
|
|
||||||
searchAndShowFilms(arg, channel, messageChannel)))
|
|
||||||
.then(event.getMessage().removeSelfReaction(WAITING))
|
|
||||||
.then();
|
|
||||||
} else return channel.createMessage("I cannot search for subtitles right now. Sorry.");
|
|
||||||
})
|
|
||||||
.then();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Mono<? extends Message> searchAndShowFilms(String arg, MessageChannel channel, MessageChannel messageChannel) {
|
|
||||||
try {
|
|
||||||
ListResponse<MovieInfo> response = OpenSubtitles.searchImdb(arg);
|
|
||||||
if (response.getStatus().getCode() == ResponseStatus.OK.getCode()) {
|
|
||||||
return messageChannel.createEmbed(
|
|
||||||
embed -> {
|
|
||||||
embed.setTitle("Results")
|
|
||||||
.setDescription("Found " + response.getData().size() + " results.")
|
|
||||||
.setColor(Color.BISMARK);
|
|
||||||
StringBuilder s = new StringBuilder("```txt\n");
|
|
||||||
for (MovieInfo info : response.getData().subList(0, Math.min(10, response.getData().size())))
|
|
||||||
s.append(String.format(FORMAT, info.getId(), info.getTitle()));
|
|
||||||
s.append("```");
|
|
||||||
embed.addField("First 10 results:", s.toString(), false);
|
|
||||||
});
|
|
||||||
} else
|
|
||||||
return messageChannel.createMessage("An error happened while fetching the results. Try again later, or contact my administrator.");
|
|
||||||
} catch (XmlRpcException e) {
|
|
||||||
return channel.createMessage("It seems like OpenSubtitles had a stroke.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,11 +3,13 @@ package xyz.vallat.louis.database;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import xyz.vallat.louis.codes.ExitCodes;
|
import xyz.vallat.louis.codes.ExitCodes;
|
||||||
|
import xyz.vallat.louis.subtitles.parser.SubtitleBlock;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class SubtitleLineManager {
|
public final class SubtitleLineManager {
|
||||||
|
|
||||||
@ -69,4 +71,8 @@ public final class SubtitleLineManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void importSubtitleLines(List<SubtitleBlock> subtitleBlocks) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user