diff --git a/source/net/filebot/util/XPathUtilities.java b/source/net/filebot/util/XPathUtilities.java index 8d10a4ec..6aef9972 100644 --- a/source/net/filebot/util/XPathUtilities.java +++ b/source/net/filebot/util/XPathUtilities.java @@ -90,6 +90,14 @@ public final class XPathUtilities { return null; } + public static Integer getIntegerAttribute(String attribute, Node node) { + try { + return new Scanner(getAttribute(attribute, node)).useDelimiter("\\D+").nextInt(); + } catch (Exception e) { + return null; + } + } + /** * Get text content of the first child node matching the given node name. Use this method instead of {@link #selectString(String, Object)} whenever xpath support is not required, because it is much faster, especially for large documents. * diff --git a/source/net/filebot/web/AnidbClient.java b/source/net/filebot/web/AnidbClient.java index 1d32d2a8..0ce36129 100644 --- a/source/net/filebot/web/AnidbClient.java +++ b/source/net/filebot/web/AnidbClient.java @@ -8,6 +8,7 @@ import static net.filebot.web.WebRequest.*; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -23,6 +24,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import javax.swing.Icon; @@ -124,6 +126,20 @@ public class AnidbClient extends AbstractEpisodeListProvider { seriesInfo.setRatingCount(new Integer(selectString("anime/ratings/permanent/@count", dom))); seriesInfo.setStartDate(SimpleDate.parse(selectString("anime/startdate", dom), "yyyy-MM-dd")); + // add categories ordered by weight as genres + // * only use categories with weight >= 400 + // * sort by weight (descending) + // * limit to 5 genres + seriesInfo.setGenres(selectNodes("anime/categories/category", dom).stream().map(categoryNode -> { + String name = getTextContent("name", categoryNode); + Integer weight = getIntegerAttribute("weight", categoryNode); + return new SimpleImmutableEntry(name, weight); + }).filter(nw -> { + return nw.getKey() != null && nw.getValue() != null && nw.getKey().length() > 0 && nw.getValue() >= 400; + }).sorted((a, b) -> { + return b.getValue().compareTo(a.getValue()); + }).map(it -> it.getKey()).limit(5).collect(Collectors.toList())); + // parse episode data String animeTitle = selectString("anime/titles/title[@type='official' and @lang='" + locale.getLanguage() + "']", dom); if (animeTitle == null || animeTitle.length() == 0) {