use of org.nzbhydra.config.Category in project nzbhydra2 by theotherp.
the class JsonConfigMigration method migrateCategories.
protected List<String> migrateCategories(Categories oldCategories, CategoriesConfig newCategories) {
// Will only migrate categories that exist under that name in the new config
List<String> messages = new ArrayList<>();
newCategories.setEnableCategorySizes(oldCategories.isEnableCategorySizes());
for (Category newCategory : newCategories.getCategories()) {
org.nzbhydra.migration.configmapping.Category oldCat = oldCategories.getCategories().get(newCategory.getName().replace(" ", "").toLowerCase());
if (oldCat != null) {
newCategory.setApplyRestrictionsType(searchSourceRestrictionMap.getOrDefault(oldCat.getApplyRestrictions(), SearchSourceRestriction.NONE));
newCategory.setForbiddenRegex(oldCat.getForbiddenRegex());
newCategory.setForbiddenWords(oldCat.getForbiddenWords() == null ? new ArrayList<>() : oldCat.getForbiddenWords());
newCategory.setMinSizePreset(oldCat.getMin());
newCategory.setMaxSizePreset(oldCat.getMax());
newCategory.setNewznabCategories(oldCat.getNewznabCategories() == null ? new ArrayList<>() : oldCat.getNewznabCategories());
newCategory.setRequiredRegex(oldCat.getRequiredRegex());
if (oldCat.getRequiredWords() != null && !oldCat.getRequiredWords().isEmpty()) {
newCategory.setRequiredWords(oldCat.getRequiredWords());
logAsWarningAndAdd(messages, "Behavior for required words changed: Now *all* words must be present");
} else {
newCategory.setRequiredWords(new ArrayList<>());
}
newCategory.setIgnoreResultsFrom(searchSourceRestrictionMap.getOrDefault(oldCat.getIgnoreResults(), SearchSourceRestriction.NONE));
}
}
return messages;
}
use of org.nzbhydra.config.Category in project nzbhydra2 by theotherp.
the class JsonConfigMigration method checkCapsForEnabledNewznabIndexers.
private void checkCapsForEnabledNewznabIndexers(List<String> messages, Map<String, Boolean> originalEnabledState, List<IndexerConfig> indexerConfigs) {
List<IndexerConfig> enabledNewznabIndexers = indexerConfigs.stream().filter(x -> (x.getSearchModuleType() == SearchModuleType.NEWZNAB || x.getSearchModuleType() == SearchModuleType.TORZNAB) && originalEnabledState.get(x.getName())).collect(Collectors.toList());
if (!enabledNewznabIndexers.isEmpty()) {
logger.info("Checking caps and getting category mapping infos for all previously enabled newznab/torznab indexers");
ExecutorService executor = Executors.newFixedThreadPool(enabledNewznabIndexers.size());
List<Callable<CheckCapsResponse>> callables = enabledNewznabIndexers.stream().<Callable<CheckCapsResponse>>map(indexerConfig -> () -> newznabChecker.checkCaps(indexerConfig)).collect(Collectors.toList());
try {
List<Future<CheckCapsResponse>> futures = executor.invokeAll(callables);
for (Future<CheckCapsResponse> future : futures) {
try {
CheckCapsResponse checkCapsRespone = future.get();
IndexerConfig indexerConfig = checkCapsRespone.getIndexerConfig();
if (checkCapsRespone.isConfigComplete()) {
logger.info("Successfully checked caps of {}. Setting it enabled now", indexerConfig.getName());
indexerConfig.setState(IndexerConfig.State.ENABLED);
indexerConfig = checkCapsRespone.getIndexerConfig();
enabledNewznabIndexers.set(enabledNewznabIndexers.indexOf(indexerConfig), indexerConfig);
if (!checkCapsRespone.isAllCapsChecked()) {
logAsWarningAndAdd(messages, "The caps check for " + indexerConfig.getName() + " was not completed. You should trigger it manually from the config at a later point.");
}
} else {
logAsWarningAndAdd(messages, "Caps check for " + indexerConfig.getName() + " failed. You'll need to repeat it manually from the config section before you can use the indexer");
}
} catch (ExecutionException e) {
logAsWarningAndAdd(messages, "Caps check for an indexer failed. You'll need to repeat it manually from the config section before you can use the indexer");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
boolean anyDisabledNewznabIndexer = indexerConfigs.stream().anyMatch(x -> (x.getSearchModuleType() == SearchModuleType.NEWZNAB || x.getSearchModuleType() == SearchModuleType.TORZNAB) && originalEnabledState.get(x.getName()));
if (anyDisabledNewznabIndexer) {
logAsWarningAndAdd(messages, "Disabled newznab indexer(s) need to be caps-checked before they can be enabled");
}
}
use of org.nzbhydra.config.Category in project nzbhydra2 by theotherp.
the class SqliteMigration method migrateSearches.
protected Map<Integer, SearchEntity> migrateSearches() throws SQLException {
Map<Integer, SearchEntity> oldIdToNewEntity = new HashMap<>();
Map<String, String> categoryMap = categoryProvider.getCategories().stream().map(Category::getName).collect(Collectors.toMap(x -> x.replace(" ", "").toLowerCase(), Function.identity()));
Map<String, SearchType> oldTypeToNewMap = new HashMap<>();
oldTypeToNewMap.put("general", SearchType.SEARCH);
oldTypeToNewMap.put("book", SearchType.BOOK);
oldTypeToNewMap.put("movie", SearchType.MOVIE);
oldTypeToNewMap.put("tv", SearchType.TVSEARCH);
oldTypeToNewMap.put("audio", SearchType.MUSIC);
Map<String, IdType> oldIdTypeToNewMap = new HashMap<>();
oldIdTypeToNewMap.put("rid", IdType.TVRAGE);
oldIdTypeToNewMap.put("tvdbid", IdType.TVDB);
oldIdTypeToNewMap.put("imdbid", IdType.IMDB);
oldIdTypeToNewMap.put("tmdbid", IdType.TMDB);
Statement statement = connection.createStatement();
int searches = getCount(statement, "search");
logger.info("Migrating {} searches from old database", searches);
eventPublisher.publishEvent(new MigrationMessageEvent("Migrating " + searches + " search entries"));
ResultSet oldSearches = statement.executeQuery("SELECT * FROM search");
boolean hasAuthor = hasColumn(oldSearches, "author");
boolean hasTitle = hasColumn(oldSearches, "title");
int skippedSearches = 0;
while (oldSearches.next()) {
try {
SearchEntity entity = new SearchEntity();
String oldCategory = oldSearches.getString("category");
String newCategory = (!Strings.isNullOrEmpty(oldCategory) && categoryMap.containsKey(oldCategory.toLowerCase())) ? categoryMap.get(oldCategory.toLowerCase()) : "All";
entity.setCategoryName(newCategory);
entity.setUsername(oldSearches.getString("username"));
entity.setSeason(oldSearches.getObject("season") != null ? oldSearches.getInt("season") : null);
entity.setEpisode(oldSearches.getString("episode"));
entity.setQuery(oldSearches.getString("query"));
if (hasAuthor) {
entity.setAuthor(oldSearches.getString("author"));
}
if (hasTitle) {
entity.setTitle(oldSearches.getString("title"));
}
entity.setSearchType(oldTypeToNewMap.getOrDefault(oldSearches.getString("type"), SearchType.SEARCH));
if (oldSearches.getString("identifier_key") != null && oldSearches.getString("identifier_value") != null && oldIdTypeToNewMap.containsKey(oldSearches.getString("identifier_key"))) {
String identifierKey = oldIdTypeToNewMap.get(oldSearches.getString("identifier_key")).name();
IdentifierKeyValuePair keyValuePair = new IdentifierKeyValuePair(identifierKey, oldSearches.getString("identifier_value"));
entity.setIdentifiers(Sets.newHashSet(keyValuePair));
}
entity.setSource((oldSearches.getBoolean("internal")) ? SearchSource.INTERNAL : SearchSource.API);
Instant time;
String timeString = oldSearches.getString("time");
time = timestampToInstant(timeString);
entity.setTime(time);
oldIdToNewEntity.put(oldSearches.getInt("id"), entity);
} catch (SQLException e) {
logger.error("Problem while migrating search", e);
skippedSearches++;
}
}
logger.info("Saving search entities to database");
searchRepository.save(oldIdToNewEntity.values());
if (skippedSearches > 0) {
String message = "Skipped " + skippedSearches + " of " + (skippedSearches + oldIdToNewEntity.size()) + " searches because the database entries could not be read";
logger.warn(message);
eventPublisher.publishEvent(new MigrationMessageEvent(message));
} else {
logger.info("Successfully migrated searches from old database");
eventPublisher.publishEvent(new MigrationMessageEvent("Successfully migrated searches from old database"));
}
return oldIdToNewEntity;
}
use of org.nzbhydra.config.Category in project nzbhydra2 by theotherp.
the class Newznab method computeCategory.
protected void computeCategory(SearchResultItem searchResultItem, List<Integer> newznabCategories) {
if (!newznabCategories.isEmpty()) {
Integer mostSpecific = newznabCategories.stream().max(Integer::compareTo).get();
IndexerCategoryConfig mapping = config.getCategoryMapping();
Category category;
if (mapping == null) {
// May be the case in some corner cases
category = categoryProvider.fromSearchNewznabCategories(newznabCategories, categoryProvider.getNotAvailable());
searchResultItem.setOriginalCategory(categoryProvider.getNotAvailable().getName());
} else {
category = idToCategory.computeIfAbsent(mostSpecific, x -> {
Optional<Category> categoryOptional = Optional.empty();
if (mapping.getAnime().isPresent() && Objects.equals(mapping.getAnime().get(), mostSpecific)) {
categoryOptional = categoryProvider.fromSubtype(Subtype.ANIME);
} else if (mapping.getAudiobook().isPresent() && Objects.equals(mapping.getAudiobook().get(), mostSpecific)) {
categoryOptional = categoryProvider.fromSubtype(Subtype.AUDIOBOOK);
} else if (mapping.getEbook().isPresent() && Objects.equals(mapping.getEbook().get(), mostSpecific)) {
categoryOptional = categoryProvider.fromSubtype(Subtype.EBOOK);
} else if (mapping.getComic().isPresent() && Objects.equals(mapping.getComic().get(), mostSpecific)) {
categoryOptional = categoryProvider.fromSubtype(Subtype.COMIC);
} else if (mapping.getMagazine().isPresent() && Objects.equals(mapping.getMagazine().get(), mostSpecific)) {
categoryOptional = categoryProvider.fromSubtype(Subtype.MAGAZINE);
}
return categoryOptional.orElse(categoryProvider.fromResultNewznabCategories(newznabCategories));
});
// Use the indexer's own category mapping to build the category name
searchResultItem.setOriginalCategory(mapping.getNameFromId(mostSpecific));
}
searchResultItem.setCategory(category);
} else {
searchResultItem.setCategory(categoryProvider.getNotAvailable());
}
}
use of org.nzbhydra.config.Category in project nzbhydra2 by theotherp.
the class Newznab method parseAttributes.
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())).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) {
error("Unable to parse password value " + passwordValue);
}
}
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)) {
// Info attribute is always a link to an NFO
searchResultItem.setHasNfo(HasNfo.YES);
}
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")));
}
computeCategory(searchResultItem, newznabCategories);
if (searchResultItem.getHasNfo() == HasNfo.MAYBE && (config.getBackend() == BackendType.NNTMUX || config.getBackend() == BackendType.NZEDB)) {
// For these backends if not specified it doesn't exist
searchResultItem.setHasNfo(HasNfo.NO);
}
if (!searchResultItem.getGroup().isPresent() && !Strings.isNullOrEmpty(item.getDescription()) && item.getDescription().contains("Group:")) {
// Dog has the group in the description, perhaps others too
Matcher matcher = GROUP_PATTERN.matcher(item.getDescription());
if (matcher.matches() && !Objects.equals(matcher.group(1), "not available")) {
searchResultItem.setGroup(matcher.group(1));
}
}
}
Aggregations