X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Frhynodge%2Ftriggers%2FNewEpisodeTrigger.java;fp=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Frhynodge%2Ftriggers%2FNewEpisodeTrigger.java;h=f23869d21ff65dfddbb143299f230cdca7cff9ed;hb=6f69aff66ba5617d0bb27874014b4274bc551ab8;hp=0000000000000000000000000000000000000000;hpb=13a4fe6bece23b3dd561de657cf9bb7ea307e2b6;p=rhynodge.git diff --git a/src/main/java/net/pterodactylus/rhynodge/triggers/NewEpisodeTrigger.java b/src/main/java/net/pterodactylus/rhynodge/triggers/NewEpisodeTrigger.java new file mode 100644 index 0000000..f23869d --- /dev/null +++ b/src/main/java/net/pterodactylus/rhynodge/triggers/NewEpisodeTrigger.java @@ -0,0 +1,233 @@ +/* + * Rhynodge - NewEpisodeTrigger.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.rhynodge.triggers; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.Collection; + +import net.pterodactylus.rhynodge.Reaction; +import net.pterodactylus.rhynodge.State; +import net.pterodactylus.rhynodge.Trigger; +import net.pterodactylus.rhynodge.output.DefaultOutput; +import net.pterodactylus.rhynodge.output.Output; +import net.pterodactylus.rhynodge.states.EpisodeState; +import net.pterodactylus.rhynodge.states.EpisodeState.Episode; +import net.pterodactylus.rhynodge.states.TorrentState.TorrentFile; + +import org.apache.commons.lang3.StringEscapeUtils; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; + +/** + * {@link Trigger} implementation that compares two {@link EpisodeState}s for + * new and changed {@link Episode}s. + * + * @author David ‘Bombe’ Roden + */ +public class NewEpisodeTrigger implements Trigger { + + /** All new episodes. */ + private Collection newEpisodes; + + /** All changed episodes. */ + private Collection changedEpisodes; + + // + // TRIGGER METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public boolean triggers(State currentState, State previousState) { + checkState(currentState instanceof EpisodeState, "currentState is not a EpisodeState but a %s", currentState.getClass().getName()); + checkState(previousState instanceof EpisodeState, "previousState is not a EpisodeState but a %s", currentState.getClass().getName()); + final EpisodeState currentEpisodeState = (EpisodeState) currentState; + final EpisodeState previousEpisodeState = (EpisodeState) previousState; + + newEpisodes = Collections2.filter(currentEpisodeState.episodes(), new Predicate() { + + @Override + public boolean apply(Episode episode) { + return !previousEpisodeState.episodes().contains(episode); + } + }); + + changedEpisodes = Collections2.filter(currentEpisodeState.episodes(), new Predicate() { + + @Override + public boolean apply(Episode episode) { + if (!previousEpisodeState.episodes().contains(episode)) { + return false; + } + + /* find previous episode. */ + final Episode previousEpisode = findPreviousEpisode(episode); + + /* compare the list of torrent files. */ + Collection newTorrentFiles = Collections2.filter(episode.torrentFiles(), new Predicate() { + + @Override + public boolean apply(TorrentFile torrentFile) { + return !previousEpisode.torrentFiles().contains(torrentFile); + } + }); + + return !newTorrentFiles.isEmpty(); + } + + private Episode findPreviousEpisode(Episode episode) { + for (Episode previousStateEpisode : previousEpisodeState) { + if (previousStateEpisode.equals(episode)) { + return previousStateEpisode; + } + } + return null; + } + + }); + + return !newEpisodes.isEmpty() || !changedEpisodes.isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public Output output(Reaction reaction) { + String summary; + if (!newEpisodes.isEmpty()) { + if (!changedEpisodes.isEmpty()) { + summary = String.format("%d new and %d changed Torrent(s) for “%s!”", newEpisodes.size(), changedEpisodes.size(), reaction.name()); + } else { + summary = String.format("%d new Torrent(s) for “%s!”", newEpisodes.size(), reaction.name()); + } + } else { + summary = String.format("%d changed Torrent(s) for “%s!”", changedEpisodes.size(), reaction.name()); + } + DefaultOutput output = new DefaultOutput(summary); + output.addText("text/plain", generatePlainText(reaction, newEpisodes, changedEpisodes)); + output.addText("text/html", generateHtmlText(reaction, newEpisodes, changedEpisodes)); + return output; + } + + // + // STATIC METHODS + // + + /** + * Generates the plain text trigger output. + * + * @param reaction + * The reaction that was triggered + * @param newEpisodes + * The new episodes + * @param changedEpisodes + * The changed episodes + * @return The plain text output + */ + private static String generatePlainText(Reaction reaction, Collection newEpisodes, Collection changedEpisodes) { + StringBuilder stringBuilder = new StringBuilder(); + if (!newEpisodes.isEmpty()) { + stringBuilder.append(reaction.name()).append(" - New Episodes\n\n"); + for (Episode episode : newEpisodes) { + stringBuilder.append("- ").append(episode.identifier()).append("\n"); + for (TorrentFile torrentFile : episode) { + stringBuilder.append(" - ").append(torrentFile.name()).append(", ").append(torrentFile.size()).append("\n"); + stringBuilder.append(" Magnet: ").append(torrentFile.magnetUri()).append("\n"); + stringBuilder.append(" Download: ").append(torrentFile.downloadUri()).append("\n"); + } + } + } + if (!changedEpisodes.isEmpty()) { + stringBuilder.append(reaction.name()).append(" - Changed Episodes\n\n"); + for (Episode episode : changedEpisodes) { + stringBuilder.append("- ").append(episode.identifier()).append("\n"); + for (TorrentFile torrentFile : episode) { + stringBuilder.append(" - ").append(torrentFile.name()).append(", ").append(torrentFile.size()).append("\n"); + stringBuilder.append(" Magnet: ").append(torrentFile.magnetUri()).append("\n"); + stringBuilder.append(" Download: ").append(torrentFile.downloadUri()).append("\n"); + } + } + } + return stringBuilder.toString(); + } + + /** + * Generates the HTML trigger output. + * + * @param reaction + * The reaction that was triggered + * @param newEpisodes + * The new episodes + * @param changedEpisodes + * The changed episodes + * @return The HTML output + */ + private static String generateHtmlText(Reaction reaction, Collection newEpisodes, Collection changedEpisodes) { + StringBuilder htmlBuilder = new StringBuilder(); + htmlBuilder.append("\n"); + htmlBuilder.append("

").append(StringEscapeUtils.escapeHtml4(reaction.name())).append("

\n"); + if (!newEpisodes.isEmpty()) { + htmlBuilder.append("

New Episodes

\n"); + htmlBuilder.append("
    \n"); + for (Episode episode : newEpisodes) { + htmlBuilder.append("
  • Season ").append(episode.season()).append(", Episode ").append(episode.episode()).append("
  • \n"); + htmlBuilder.append("
      \n"); + for (TorrentFile torrentFile : episode) { + htmlBuilder.append("
    • ").append(StringEscapeUtils.escapeHtml4(torrentFile.name())).append("
    • \n"); + htmlBuilder.append("
      "); + htmlBuilder.append("").append(StringEscapeUtils.escapeHtml4(torrentFile.size())).append(", "); + htmlBuilder.append("").append(torrentFile.fileCount()).append(" file(s), "); + htmlBuilder.append("").append(torrentFile.seedCount()).append(" seed(s), "); + htmlBuilder.append("").append(torrentFile.leechCount()).append(" leecher(s)
      \n"); + htmlBuilder.append("
      Magnet "); + htmlBuilder.append("Download
      \n"); + } + htmlBuilder.append("
    \n"); + } + htmlBuilder.append("
\n"); + } + if (!changedEpisodes.isEmpty()) { + htmlBuilder.append("

Changed Episodes

\n"); + htmlBuilder.append("
    \n"); + for (Episode episode : changedEpisodes) { + htmlBuilder.append("
  • Season ").append(episode.season()).append(", Episode ").append(episode.episode()).append("
  • \n"); + htmlBuilder.append("
      \n"); + for (TorrentFile torrentFile : episode) { + htmlBuilder.append("
    • ").append(StringEscapeUtils.escapeHtml4(torrentFile.name())).append("
    • \n"); + htmlBuilder.append("
      "); + htmlBuilder.append("").append(StringEscapeUtils.escapeHtml4(torrentFile.size())).append(", "); + htmlBuilder.append("").append(torrentFile.fileCount()).append(" file(s), "); + htmlBuilder.append("").append(torrentFile.seedCount()).append(" seed(s), "); + htmlBuilder.append("").append(torrentFile.leechCount()).append(" leecher(s)
      \n"); + htmlBuilder.append("
      Magnet "); + htmlBuilder.append("Download
      \n"); + } + htmlBuilder.append("
    \n"); + } + htmlBuilder.append("
\n"); + } + htmlBuilder.append("\n"); + return htmlBuilder.toString(); + } + +}