package finders; import data.RSS; import discord4j.core.object.entity.TextChannel; import discord4j.core.object.util.Snowflake; import enums.Language; import reactor.core.publisher.Flux; import util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by steve on 12/01/2017. */ public class RSSFinder { private final static Logger LOG = LoggerFactory.getLogger(RSSFinder.class); private final static long DELTA = 10; // 10min private static boolean isStarted = false; private static Map<String, RSSFinder> rssFinders = null; private String idGuild; private String chan; private long lastRSS; public RSSFinder(String idGuild, String chan) { this(idGuild, chan, System.currentTimeMillis()); } private RSSFinder(String idGuild, String chan, long lastRSS) { this.idGuild = idGuild; this.chan = chan; this.lastRSS = lastRSS; } public synchronized void setLastRSS(long lastRSS) { this.lastRSS = lastRSS; Connexion connexion = Connexion.getInstance(); Connection connection = connexion.getConnection(); try { PreparedStatement preparedStatement = connection.prepareStatement( "UPDATE RSS_Finder SET last_update = ? WHERE id_chan = ?;"); preparedStatement.setLong(1, lastRSS); preparedStatement.setString(2, getChan()); preparedStatement.executeUpdate(); } catch (SQLException e) { LOG.error("setLastRSS", e); } } public synchronized void addToDatabase(){ if (! getRSSFinders().containsKey(getChan())) { getRSSFinders().put(getChan(), this); Connexion connexion = Connexion.getInstance(); Connection connection = connexion.getConnection(); try { PreparedStatement preparedStatement = connection.prepareStatement( "INSERT INTO RSS_Finder(id_guild, id_chan, last_update) VALUES(?, ?, ?);"); preparedStatement.setString(1, getGuildId()); preparedStatement.setString(2, getChan()); preparedStatement.setLong(3, getLastRSS()); preparedStatement.executeUpdate(); } catch (SQLException e) { LOG.error("addToDatabase", e); } } } public synchronized void removeToDatabase() { getRSSFinders().remove(getChan()); Connexion connexion = Connexion.getInstance(); Connection connection = connexion.getConnection(); try { PreparedStatement request = connection.prepareStatement("DELETE FROM RSS_Finder WHERE id_chan = ?;"); request.setString(1, getChan()); request.executeUpdate(); } catch (SQLException e) { LOG.error("removeToDatabase", e); } } public synchronized static Map<String, RSSFinder> getRSSFinders(){ if (rssFinders == null){ rssFinders = new ConcurrentHashMap<>(); Connexion connexion = Connexion.getInstance(); Connection connection = connexion.getConnection(); try { PreparedStatement query = connection.prepareStatement("SELECT id_guild, id_chan, last_update FROM RSS_Finder"); ResultSet resultSet = query.executeQuery(); while (resultSet.next()){ String idChan = resultSet.getString("id_chan"); String idGuild = resultSet.getString("id_guild"); long lastUpdate = resultSet.getLong("last_update"); ClientConfig.DISCORD() .flatMap(client -> client.getChannelById(Snowflake.of(idChan))) .filter(channel -> channel instanceof TextChannel) .map(channel -> (TextChannel) channel) .collectList().blockOptional().orElse(Collections.emptyList()) .forEach(chan -> rssFinders.put(chan.getId().asString(), new RSSFinder(idGuild, chan.getId().asString(), lastUpdate))); } } catch (SQLException e) { Reporter.report(e); LOG.error("getRSSFinders", e); } } return rssFinders; } public static void start(){ if (!isStarted) { isStarted = true; ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(() -> { Map<Language, List<RSS>> allFeeds = new HashMap<>(); for(Language lg : Language.values()) allFeeds.put(lg, RSS.getRSSFeeds(lg)); for (RSSFinder finder : getRSSFinders().values()) try { List<TextChannel> chans = ClientConfig.DISCORD() .flatMap(client -> client.getChannelById(Snowflake.of(finder.chan))).distinct() .filter(channel -> channel instanceof TextChannel) .map(channel -> (TextChannel) channel) .collectList().blockOptional().orElse(Collections.emptyList()); for(TextChannel chan : chans) { Language lg = Translator.getLanguageFrom(chan); List<RSS> rssFeeds = allFeeds.get(Translator.getLanguageFrom(chan)); long lastRSS = -1; for (RSS rss : rssFeeds) if (rss.getDate() > finder.getLastRSS()) { chan.createEmbed(spec -> rss.decorateEmbedObject(spec, lg)).subscribe(); lastRSS = rss.getDate(); } if (lastRSS != -1) finder.setLastRSS(lastRSS); } } catch(Exception e){ Reporter.report(e); LOG.error("RSSFinder", e); } }, 0, DELTA, TimeUnit.MINUTES); } } public String getChan() { return chan; } public String getGuildId() { return idGuild; } public long getLastRSS() { return lastRSS; } }