@Test public void shouldUseIndexersCategoryMappingToBuildOriginalCategoryName() throws Exception { testee.config.getCategoryMapping().setCategories(Arrays.asList(new MainCategory(5000, "TV", Arrays.asList(new SubCategory(5040, "HD"))))); NewznabXmlItem rssItem = buildBasicRssItem(); rssItem.getNewznabAttributes().add(new NewznabAttribute("category", "5040")); rssItem.getNewznabAttributes().add(new NewznabAttribute("category", "5000")); SearchResultItem searchResultItem = new SearchResultItem(); Category category = new Category(); category.setSearchType(SearchType.TVSEARCH); searchResultItem.setCategory(category); testee.parseAttributes(rssItem, searchResultItem); assertThat(searchResultItem.getOriginalCategory(), is("TV HD")); rssItem.getNewznabAttributes().clear(); rssItem.getNewznabAttributes().add(new NewznabAttribute("category", "1234")); testee.parseAttributes(rssItem, searchResultItem); assertThat(searchResultItem.getOriginalCategory(), is("N/A")); }
protected void parseAttributes(NewznabXmlItem item, SearchResultItem searchResultItem) { Map<String, String> attributes = item.getNewznabAttributes().stream().collect(Collectors.toMap(NewznabAttribute::getName, NewznabAttribute::getValue, (a, b) -> b)); List<Integer> newznabCategories = item.getNewznabAttributes().stream().filter(x -> x.getName().equals("category") && !"None".equals(x.getValue()) && !Strings.isNullOrEmpty(x.getValue())).map(newznabAttribute -> Integer.parseInt(newznabAttribute.getValue())).collect(Collectors.toList()); searchResultItem.setAttributes(attributes); if (attributes.containsKey("usenetdate")) { tryParseDate(attributes.get("usenetdate")).ifPresent(searchResultItem::setUsenetDate); } if (attributes.containsKey("password")) { String passwordValue = attributes.get("password"); try { if (Integer.parseInt(passwordValue) > 0) { searchResultItem.setPassworded(true); } } catch (NumberFormatException e) { searchResultItem.setPassworded(true); } } if (attributes.containsKey("nfo")) { searchResultItem.setHasNfo(attributes.get("nfo").equals("1") ? HasNfo.YES : HasNfo.NO); } if (attributes.containsKey("info") && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.YES); } Arrays.asList("coverurl", "cover").forEach(x -> { if (attributes.containsKey(x) && !attributes.get(x).equals("not available") && (attributes.get(x).toLowerCase().endsWith(".jpg") || attributes.get(x).toLowerCase().endsWith(".jpeg") || attributes.get(x).toLowerCase().endsWith(".png"))) { searchResultItem.setCover(attributes.get(x)); } }); if (attributes.containsKey("poster") && !attributes.get("poster").equals("not available")) { searchResultItem.setPoster(attributes.get("poster")); } if (attributes.containsKey("group") && !attributes.get("group").equals("not available")) { searchResultItem.setGroup(attributes.get("group")); } if (attributes.containsKey("files")) { searchResultItem.setFiles(Integer.valueOf(attributes.get("files"))); } if (attributes.containsKey("comments")) { searchResultItem.setCommentsCount(Integer.valueOf(attributes.get("comments"))); } if (attributes.containsKey("grabs")) { searchResultItem.setGrabs(Integer.valueOf(attributes.get("grabs"))); } if (attributes.containsKey("guid")) { searchResultItem.setIndexerGuid(attributes.get("guid")); } if (attributes.containsKey("size")) { searchResultItem.setSize(Long.valueOf(attributes.get("size"))); } if (attributes.containsKey("source")) { searchResultItem.setSource(attributes.get("source")); } computeCategory(searchResultItem, newznabCategories); if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.NO); } if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) { Matcher matcher = GROUP_PATTERN.matcher(item.getDescription()); if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) { searchResultItem.setGroup(matcher.group(1)); } } try { if (searchResultItem.getCategory().getSearchType() == SearchType.TVSEARCH) { if (searchResultItem.getAttributes().containsKey("season")) { searchResultItem.getAttributes().put("season", searchResultItem.getAttributes().get("season").replaceAll("[sS]", "")); } if (searchResultItem.getAttributes().containsKey("episode")) { searchResultItem.getAttributes().put("episode", searchResultItem.getAttributes().get("episode").replaceAll("[eE]", "")); } if (searchResultItem.getAttributes().containsKey("showtitle")) { searchResultItem.getAttributes().put("showtitle", searchResultItem.getAttributes().get("showtitle")); } if (!attributes.containsKey("season") || !attributes.containsKey("episode") || !attributes.containsKey("showtitle")) { Matcher matcher = TV_PATTERN.matcher(item.getTitle()); if (matcher.find()) { putGroupMatchIfFound(searchResultItem, matcher, "season", "season"); putGroupMatchIfFound(searchResultItem, matcher, "season2", "season"); putGroupMatchIfFound(searchResultItem, matcher, "episode", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "episode2", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "showtitle", "showtitle"); } } if (attributes.containsKey("season")) { attributes.put("season", tryParseInt(attributes.get("season").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("episode")) { attributes.put("episode", tryParseInt(attributes.get("episode").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("showtitle")) { attributes.put("showtitle", attributes.get("showtitle").replaceAll("\\W", "").toLowerCase()); } } } catch (NumberFormatException e) { } }
Newznab extends Indexer<Xml> { protected void parseAttributes(NewznabXmlItem item, SearchResultItem searchResultItem) { Map<String, String> attributes = item.getNewznabAttributes().stream().collect(Collectors.toMap(NewznabAttribute::getName, NewznabAttribute::getValue, (a, b) -> b)); List<Integer> newznabCategories = item.getNewznabAttributes().stream().filter(x -> x.getName().equals("category") && !"None".equals(x.getValue()) && !Strings.isNullOrEmpty(x.getValue())).map(newznabAttribute -> Integer.parseInt(newznabAttribute.getValue())).collect(Collectors.toList()); searchResultItem.setAttributes(attributes); if (attributes.containsKey("usenetdate")) { tryParseDate(attributes.get("usenetdate")).ifPresent(searchResultItem::setUsenetDate); } if (attributes.containsKey("password")) { String passwordValue = attributes.get("password"); try { if (Integer.parseInt(passwordValue) > 0) { searchResultItem.setPassworded(true); } } catch (NumberFormatException e) { searchResultItem.setPassworded(true); } } if (attributes.containsKey("nfo")) { searchResultItem.setHasNfo(attributes.get("nfo").equals("1") ? HasNfo.YES : HasNfo.NO); } if (attributes.containsKey("info") && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.YES); } Arrays.asList("coverurl", "cover").forEach(x -> { if (attributes.containsKey(x) && !attributes.get(x).equals("not available") && (attributes.get(x).toLowerCase().endsWith(".jpg") || attributes.get(x).toLowerCase().endsWith(".jpeg") || attributes.get(x).toLowerCase().endsWith(".png"))) { searchResultItem.setCover(attributes.get(x)); } }); if (attributes.containsKey("poster") && !attributes.get("poster").equals("not available")) { searchResultItem.setPoster(attributes.get("poster")); } if (attributes.containsKey("group") && !attributes.get("group").equals("not available")) { searchResultItem.setGroup(attributes.get("group")); } if (attributes.containsKey("files")) { searchResultItem.setFiles(Integer.valueOf(attributes.get("files"))); } if (attributes.containsKey("comments")) { searchResultItem.setCommentsCount(Integer.valueOf(attributes.get("comments"))); } if (attributes.containsKey("grabs")) { searchResultItem.setGrabs(Integer.valueOf(attributes.get("grabs"))); } if (attributes.containsKey("guid")) { searchResultItem.setIndexerGuid(attributes.get("guid")); } if (attributes.containsKey("size")) { searchResultItem.setSize(Long.valueOf(attributes.get("size"))); } if (attributes.containsKey("source")) { searchResultItem.setSource(attributes.get("source")); } computeCategory(searchResultItem, newznabCategories); if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.NO); } if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) { Matcher matcher = GROUP_PATTERN.matcher(item.getDescription()); if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) { searchResultItem.setGroup(matcher.group(1)); } } try { if (searchResultItem.getCategory().getSearchType() == SearchType.TVSEARCH) { if (searchResultItem.getAttributes().containsKey("season")) { searchResultItem.getAttributes().put("season", searchResultItem.getAttributes().get("season").replaceAll("[sS]", "")); } if (searchResultItem.getAttributes().containsKey("episode")) { searchResultItem.getAttributes().put("episode", searchResultItem.getAttributes().get("episode").replaceAll("[eE]", "")); } if (searchResultItem.getAttributes().containsKey("showtitle")) { searchResultItem.getAttributes().put("showtitle", searchResultItem.getAttributes().get("showtitle")); } if (!attributes.containsKey("season") || !attributes.containsKey("episode") || !attributes.containsKey("showtitle")) { Matcher matcher = TV_PATTERN.matcher(item.getTitle()); if (matcher.find()) { putGroupMatchIfFound(searchResultItem, matcher, "season", "season"); putGroupMatchIfFound(searchResultItem, matcher, "season2", "season"); putGroupMatchIfFound(searchResultItem, matcher, "episode", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "episode2", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "showtitle", "showtitle"); } } if (attributes.containsKey("season")) { attributes.put("season", tryParseInt(attributes.get("season").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("episode")) { attributes.put("episode", tryParseInt(attributes.get("episode").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("showtitle")) { attributes.put("showtitle", attributes.get("showtitle").replaceAll("\\W", "").toLowerCase()); } } } catch (NumberFormatException e) { } } }
Newznab extends Indexer<Xml> { protected void parseAttributes(NewznabXmlItem item, SearchResultItem searchResultItem) { Map<String, String> attributes = item.getNewznabAttributes().stream().collect(Collectors.toMap(NewznabAttribute::getName, NewznabAttribute::getValue, (a, b) -> b)); List<Integer> newznabCategories = item.getNewznabAttributes().stream().filter(x -> x.getName().equals("category") && !"None".equals(x.getValue()) && !Strings.isNullOrEmpty(x.getValue())).map(newznabAttribute -> Integer.parseInt(newznabAttribute.getValue())).collect(Collectors.toList()); searchResultItem.setAttributes(attributes); if (attributes.containsKey("usenetdate")) { tryParseDate(attributes.get("usenetdate")).ifPresent(searchResultItem::setUsenetDate); } if (attributes.containsKey("password")) { String passwordValue = attributes.get("password"); try { if (Integer.parseInt(passwordValue) > 0) { searchResultItem.setPassworded(true); } } catch (NumberFormatException e) { searchResultItem.setPassworded(true); } } if (attributes.containsKey("nfo")) { searchResultItem.setHasNfo(attributes.get("nfo").equals("1") ? HasNfo.YES : HasNfo.NO); } if (attributes.containsKey("info") && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.YES); } Arrays.asList("coverurl", "cover").forEach(x -> { if (attributes.containsKey(x) && !attributes.get(x).equals("not available") && (attributes.get(x).toLowerCase().endsWith(".jpg") || attributes.get(x).toLowerCase().endsWith(".jpeg") || attributes.get(x).toLowerCase().endsWith(".png"))) { searchResultItem.setCover(attributes.get(x)); } }); if (attributes.containsKey("poster") && !attributes.get("poster").equals("not available")) { searchResultItem.setPoster(attributes.get("poster")); } if (attributes.containsKey("group") && !attributes.get("group").equals("not available")) { searchResultItem.setGroup(attributes.get("group")); } if (attributes.containsKey("files")) { searchResultItem.setFiles(Integer.valueOf(attributes.get("files"))); } if (attributes.containsKey("comments")) { searchResultItem.setCommentsCount(Integer.valueOf(attributes.get("comments"))); } if (attributes.containsKey("grabs")) { searchResultItem.setGrabs(Integer.valueOf(attributes.get("grabs"))); } if (attributes.containsKey("guid")) { searchResultItem.setIndexerGuid(attributes.get("guid")); } if (attributes.containsKey("size")) { searchResultItem.setSize(Long.valueOf(attributes.get("size"))); } if (attributes.containsKey("source")) { searchResultItem.setSource(attributes.get("source")); } computeCategory(searchResultItem, newznabCategories); if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.NO); } if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) { Matcher matcher = GROUP_PATTERN.matcher(item.getDescription()); if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) { searchResultItem.setGroup(matcher.group(1)); } } try { if (searchResultItem.getCategory().getSearchType() == SearchType.TVSEARCH) { if (searchResultItem.getAttributes().containsKey("season")) { searchResultItem.getAttributes().put("season", searchResultItem.getAttributes().get("season").replaceAll("[sS]", "")); } if (searchResultItem.getAttributes().containsKey("episode")) { searchResultItem.getAttributes().put("episode", searchResultItem.getAttributes().get("episode").replaceAll("[eE]", "")); } if (searchResultItem.getAttributes().containsKey("showtitle")) { searchResultItem.getAttributes().put("showtitle", searchResultItem.getAttributes().get("showtitle")); } if (!attributes.containsKey("season") || !attributes.containsKey("episode") || !attributes.containsKey("showtitle")) { Matcher matcher = TV_PATTERN.matcher(item.getTitle()); if (matcher.find()) { putGroupMatchIfFound(searchResultItem, matcher, "season", "season"); putGroupMatchIfFound(searchResultItem, matcher, "season2", "season"); putGroupMatchIfFound(searchResultItem, matcher, "episode", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "episode2", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "showtitle", "showtitle"); } } if (attributes.containsKey("season")) { attributes.put("season", tryParseInt(attributes.get("season").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("episode")) { attributes.put("episode", tryParseInt(attributes.get("episode").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("showtitle")) { attributes.put("showtitle", attributes.get("showtitle").replaceAll("\\W", "").toLowerCase()); } } } catch (NumberFormatException e) { } }  }
Newznab extends Indexer<Xml> { protected void parseAttributes(NewznabXmlItem item, SearchResultItem searchResultItem) { Map<String, String> attributes = item.getNewznabAttributes().stream().collect(Collectors.toMap(NewznabAttribute::getName, NewznabAttribute::getValue, (a, b) -> b)); List<Integer> newznabCategories = item.getNewznabAttributes().stream().filter(x -> x.getName().equals("category") && !"None".equals(x.getValue()) && !Strings.isNullOrEmpty(x.getValue())).map(newznabAttribute -> Integer.parseInt(newznabAttribute.getValue())).collect(Collectors.toList()); searchResultItem.setAttributes(attributes); if (attributes.containsKey("usenetdate")) { tryParseDate(attributes.get("usenetdate")).ifPresent(searchResultItem::setUsenetDate); } if (attributes.containsKey("password")) { String passwordValue = attributes.get("password"); try { if (Integer.parseInt(passwordValue) > 0) { searchResultItem.setPassworded(true); } } catch (NumberFormatException e) { searchResultItem.setPassworded(true); } } if (attributes.containsKey("nfo")) { searchResultItem.setHasNfo(attributes.get("nfo").equals("1") ? HasNfo.YES : HasNfo.NO); } if (attributes.containsKey("info") && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.YES); } Arrays.asList("coverurl", "cover").forEach(x -> { if (attributes.containsKey(x) && !attributes.get(x).equals("not available") && (attributes.get(x).toLowerCase().endsWith(".jpg") || attributes.get(x).toLowerCase().endsWith(".jpeg") || attributes.get(x).toLowerCase().endsWith(".png"))) { searchResultItem.setCover(attributes.get(x)); } }); if (attributes.containsKey("poster") && !attributes.get("poster").equals("not available")) { searchResultItem.setPoster(attributes.get("poster")); } if (attributes.containsKey("group") && !attributes.get("group").equals("not available")) { searchResultItem.setGroup(attributes.get("group")); } if (attributes.containsKey("files")) { searchResultItem.setFiles(Integer.valueOf(attributes.get("files"))); } if (attributes.containsKey("comments")) { searchResultItem.setCommentsCount(Integer.valueOf(attributes.get("comments"))); } if (attributes.containsKey("grabs")) { searchResultItem.setGrabs(Integer.valueOf(attributes.get("grabs"))); } if (attributes.containsKey("guid")) { searchResultItem.setIndexerGuid(attributes.get("guid")); } if (attributes.containsKey("size")) { searchResultItem.setSize(Long.valueOf(attributes.get("size"))); } if (attributes.containsKey("source")) { searchResultItem.setSource(attributes.get("source")); } computeCategory(searchResultItem, newznabCategories); if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.NO); } if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) { Matcher matcher = GROUP_PATTERN.matcher(item.getDescription()); if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) { searchResultItem.setGroup(matcher.group(1)); } } try { if (searchResultItem.getCategory().getSearchType() == SearchType.TVSEARCH) { if (searchResultItem.getAttributes().containsKey("season")) { searchResultItem.getAttributes().put("season", searchResultItem.getAttributes().get("season").replaceAll("[sS]", "")); } if (searchResultItem.getAttributes().containsKey("episode")) { searchResultItem.getAttributes().put("episode", searchResultItem.getAttributes().get("episode").replaceAll("[eE]", "")); } if (searchResultItem.getAttributes().containsKey("showtitle")) { searchResultItem.getAttributes().put("showtitle", searchResultItem.getAttributes().get("showtitle")); } if (!attributes.containsKey("season") || !attributes.containsKey("episode") || !attributes.containsKey("showtitle")) { Matcher matcher = TV_PATTERN.matcher(item.getTitle()); if (matcher.find()) { putGroupMatchIfFound(searchResultItem, matcher, "season", "season"); putGroupMatchIfFound(searchResultItem, matcher, "season2", "season"); putGroupMatchIfFound(searchResultItem, matcher, "episode", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "episode2", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "showtitle", "showtitle"); } } if (attributes.containsKey("season")) { attributes.put("season", tryParseInt(attributes.get("season").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("episode")) { attributes.put("episode", tryParseInt(attributes.get("episode").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("showtitle")) { attributes.put("showtitle", attributes.get("showtitle").replaceAll("\\W", "").toLowerCase()); } } } catch (NumberFormatException e) { } }  @Override NfoResult getNfo(String guid); }
Newznab extends Indexer<Xml> { protected void parseAttributes(NewznabXmlItem item, SearchResultItem searchResultItem) { Map<String, String> attributes = item.getNewznabAttributes().stream().collect(Collectors.toMap(NewznabAttribute::getName, NewznabAttribute::getValue, (a, b) -> b)); List<Integer> newznabCategories = item.getNewznabAttributes().stream().filter(x -> x.getName().equals("category") && !"None".equals(x.getValue()) && !Strings.isNullOrEmpty(x.getValue())).map(newznabAttribute -> Integer.parseInt(newznabAttribute.getValue())).collect(Collectors.toList()); searchResultItem.setAttributes(attributes); if (attributes.containsKey("usenetdate")) { tryParseDate(attributes.get("usenetdate")).ifPresent(searchResultItem::setUsenetDate); } if (attributes.containsKey("password")) { String passwordValue = attributes.get("password"); try { if (Integer.parseInt(passwordValue) > 0) { searchResultItem.setPassworded(true); } } catch (NumberFormatException e) { searchResultItem.setPassworded(true); } } if (attributes.containsKey("nfo")) { searchResultItem.setHasNfo(attributes.get("nfo").equals("1") ? HasNfo.YES : HasNfo.NO); } if (attributes.containsKey("info") && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.YES); } Arrays.asList("coverurl", "cover").forEach(x -> { if (attributes.containsKey(x) && !attributes.get(x).equals("not available") && (attributes.get(x).toLowerCase().endsWith(".jpg") || attributes.get(x).toLowerCase().endsWith(".jpeg") || attributes.get(x).toLowerCase().endsWith(".png"))) { searchResultItem.setCover(attributes.get(x)); } }); if (attributes.containsKey("poster") && !attributes.get("poster").equals("not available")) { searchResultItem.setPoster(attributes.get("poster")); } if (attributes.containsKey("group") && !attributes.get("group").equals("not available")) { searchResultItem.setGroup(attributes.get("group")); } if (attributes.containsKey("files")) { searchResultItem.setFiles(Integer.valueOf(attributes.get("files"))); } if (attributes.containsKey("comments")) { searchResultItem.setCommentsCount(Integer.valueOf(attributes.get("comments"))); } if (attributes.containsKey("grabs")) { searchResultItem.setGrabs(Integer.valueOf(attributes.get("grabs"))); } if (attributes.containsKey("guid")) { searchResultItem.setIndexerGuid(attributes.get("guid")); } if (attributes.containsKey("size")) { searchResultItem.setSize(Long.valueOf(attributes.get("size"))); } if (attributes.containsKey("source")) { searchResultItem.setSource(attributes.get("source")); } computeCategory(searchResultItem, newznabCategories); if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) { searchResultItem.setHasNfo(HasNfo.NO); } if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) { Matcher matcher = GROUP_PATTERN.matcher(item.getDescription()); if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) { searchResultItem.setGroup(matcher.group(1)); } } try { if (searchResultItem.getCategory().getSearchType() == SearchType.TVSEARCH) { if (searchResultItem.getAttributes().containsKey("season")) { searchResultItem.getAttributes().put("season", searchResultItem.getAttributes().get("season").replaceAll("[sS]", "")); } if (searchResultItem.getAttributes().containsKey("episode")) { searchResultItem.getAttributes().put("episode", searchResultItem.getAttributes().get("episode").replaceAll("[eE]", "")); } if (searchResultItem.getAttributes().containsKey("showtitle")) { searchResultItem.getAttributes().put("showtitle", searchResultItem.getAttributes().get("showtitle")); } if (!attributes.containsKey("season") || !attributes.containsKey("episode") || !attributes.containsKey("showtitle")) { Matcher matcher = TV_PATTERN.matcher(item.getTitle()); if (matcher.find()) { putGroupMatchIfFound(searchResultItem, matcher, "season", "season"); putGroupMatchIfFound(searchResultItem, matcher, "season2", "season"); putGroupMatchIfFound(searchResultItem, matcher, "episode", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "episode2", "episode"); putGroupMatchIfFound(searchResultItem, matcher, "showtitle", "showtitle"); } } if (attributes.containsKey("season")) { attributes.put("season", tryParseInt(attributes.get("season").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("episode")) { attributes.put("episode", tryParseInt(attributes.get("episode").replaceAll("\\D", "").toLowerCase())); } if (attributes.containsKey("showtitle")) { attributes.put("showtitle", attributes.get("showtitle").replaceAll("\\W", "").toLowerCase()); } } } catch (NumberFormatException e) { } }  @Override NfoResult getNfo(String guid);  }