X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Frhynodge%2Ffilters%2FEpisodeFilter.java;h=6aa3e1f2139c6d1b42f879a99bdd923a3b413f17;hb=a861000ec60248ede82ee5137a7017098b616848;hp=6c6cfc05391c0bbf74ff4b1bbfdb47c9fc6e06de;hpb=c348b96a42d161337fe7e44b7f28c6c29072872a;p=rhynodge.git diff --git a/src/main/java/net/pterodactylus/rhynodge/filters/EpisodeFilter.java b/src/main/java/net/pterodactylus/rhynodge/filters/EpisodeFilter.java index 6c6cfc0..6aa3e1f 100644 --- a/src/main/java/net/pterodactylus/rhynodge/filters/EpisodeFilter.java +++ b/src/main/java/net/pterodactylus/rhynodge/filters/EpisodeFilter.java @@ -17,9 +17,12 @@ package net.pterodactylus.rhynodge.filters; +import static com.google.common.base.Optional.absent; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.FluentIterable.from; +import static java.util.Arrays.asList; -import java.util.LinkedHashMap; +import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,6 +34,13 @@ import net.pterodactylus.rhynodge.states.FailedState; import net.pterodactylus.rhynodge.states.TorrentState; import net.pterodactylus.rhynodge.states.TorrentState.TorrentFile; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import org.apache.log4j.Logger; +import org.jetbrains.annotations.NotNull; + /** * {@link Filter} implementation that extracts {@link Episode} information from * the {@link TorrentFile}s contained in a {@link TorrentState}. @@ -39,8 +49,10 @@ import net.pterodactylus.rhynodge.states.TorrentState.TorrentFile; */ public class EpisodeFilter implements Filter { + private static final Logger logger = Logger.getLogger(EpisodeFilter.class); + /** The pattern to parse episode information from the filename. */ - private static Pattern episodePattern = Pattern.compile("S(\\d{2})E(\\d{2})|[^\\d](\\d{1,2})x(\\d{2})[^\\d]"); + private static final Collection episodePatterns = asList(Pattern.compile("[Ss](\\d{2})[Ee](\\d{2})"), Pattern.compile("[^\\d](\\d{1,2})x(\\d{2})[^\\d]")); // // FILTER METHODS @@ -49,28 +61,25 @@ public class EpisodeFilter implements Filter { /** * {@inheritDoc} */ + @NotNull @Override - public State filter(State state) { + public State filter(@NotNull State state) { if (!state.success()) { return FailedState.from(state); } checkState(state instanceof TorrentState, "state is not a TorrentState but a %s!", state.getClass()); TorrentState torrentState = (TorrentState) state; - LinkedHashMap episodes = new LinkedHashMap(); + final Multimap episodes = HashMultimap.create(); for (TorrentFile torrentFile : torrentState) { - Episode episode = extractEpisode(torrentFile); - if (episode == null) { + Optional episode = extractEpisode(torrentFile); + if (!episode.isPresent()) { continue; } - if (!episodes.containsKey(episode)) { - episodes.put(episode, episode); - } - episode = episodes.get(episode); - episode.addTorrentFile(torrentFile); + episodes.put(episode.get(), torrentFile); } - return new EpisodeState(episodes.values()); + return new EpisodeState(from(episodes.keySet()).transform(episodeFiller(episodes)).toSet()); } // @@ -78,27 +87,49 @@ public class EpisodeFilter implements Filter { // /** + * Returns a function that creates an {@link Episode} that contains all {@link + * TorrentFile}s. + * + * @param episodeTorrents + * A multimap mapping episodes to torrent files. + * @return The function that performs the extraction of torrent files + */ + private static Function episodeFiller(final Multimap episodeTorrents) { + return new Function() { + @Override + public Episode apply(Episode episode) { + Episode completeEpisode = new Episode(episode.season(), episode.episode()); + for (TorrentFile torrentFile : episodeTorrents.get(episode)) { + completeEpisode.addTorrentFile(torrentFile); + } + return completeEpisode; + } + }; + } + + /** * Extracts episode information from the given torrent file. * * @param torrentFile - * The torrent file to extract the episode information from - * @return The extracted episode information, or {@code null} if no episode - * information could be found + * The torrent file to extract the episode information from + * @return The extracted episode information, or {@link Optional#absent()} if + * no episode information could be found */ - private static Episode extractEpisode(TorrentFile torrentFile) { - Matcher matcher = episodePattern.matcher(torrentFile.name()); - if (!matcher.find()) { - return null; - } - String seasonString = matcher.group(1); - String episodeString = matcher.group(2); - if ((seasonString == null) && (episodeString == null)) { - seasonString = matcher.group(3); - episodeString = matcher.group(4); + private static Optional extractEpisode(TorrentFile torrentFile) { + logger.debug(String.format("Extracting episode from %s...", torrentFile)); + for (Pattern episodePattern : episodePatterns) { + Matcher matcher = episodePattern.matcher(torrentFile.name()); + if (!matcher.find() || matcher.groupCount() < 2) { + continue; + } + String seasonString = matcher.group(1); + String episodeString = matcher.group(2); + logger.debug(String.format("Parsing %s and %s as season and episode...", seasonString, episodeString)); + int season = Integer.valueOf(seasonString); + int episode = Integer.valueOf(episodeString); + return Optional.of(new Episode(season, episode)); } - int season = Integer.valueOf(seasonString); - int episode = Integer.valueOf(episodeString); - return new Episode(season, episode); + return absent(); } }