Search in sources :

Example 6 with Category

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;
}
Also used : Category(org.nzbhydra.config.Category) org.nzbhydra.migration.configmapping(org.nzbhydra.migration.configmapping)

Example 7 with Category

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");
    }
}
Also used : java.util(java.util) CheckCapsResponse(org.nzbhydra.indexers.capscheck.CheckCapsResponse) URL(java.net.URL) Strings(joptsimple.internal.Strings) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) DeserializationFeature(com.fasterxml.jackson.databind.DeserializationFeature) BackendType(org.nzbhydra.indexers.Indexer.BackendType) YAMLFactory(com.fasterxml.jackson.dataformat.yaml.YAMLFactory) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) NewznabChecker(org.nzbhydra.indexers.capscheck.NewznabChecker) Category(org.nzbhydra.config.Category) Logger(org.slf4j.Logger) MalformedURLException(java.net.MalformedURLException) java.util.concurrent(java.util.concurrent) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IdType(org.nzbhydra.mediainfo.InfoProvider.IdType) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Jdk8Module(com.fasterxml.jackson.datatype.jdk8.Jdk8Module) ActionAttribute(org.nzbhydra.mapping.newznab.ActionAttribute) CategoryProvider(org.nzbhydra.searching.CategoryProvider) Component(org.springframework.stereotype.Component) org.nzbhydra.migration.configmapping(org.nzbhydra.migration.configmapping) Data(lombok.Data) MigrationMessageEvent(org.nzbhydra.migration.FromPythonMigration.MigrationMessageEvent) AllArgsConstructor(lombok.AllArgsConstructor) org.nzbhydra.config(org.nzbhydra.config) CheckCapsResponse(org.nzbhydra.indexers.capscheck.CheckCapsResponse)

Example 8 with Category

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;
}
Also used : java.sql(java.sql) java.util(java.util) org.nzbhydra.searching(org.nzbhydra.searching) Strings(joptsimple.internal.Strings) LoggerFactory(org.slf4j.LoggerFactory) LocalDateTime(java.time.LocalDateTime) Autowired(org.springframework.beans.factory.annotation.Autowired) Function(java.util.function.Function) FileDownloadEntity(org.nzbhydra.downloading.FileDownloadEntity) SearchSource(org.nzbhydra.searching.searchrequests.SearchRequest.SearchSource) FileDownloadStatus(org.nzbhydra.downloading.FileDownloadStatus) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) ZoneOffset(java.time.ZoneOffset) TypeReference(com.fasterxml.jackson.core.type.TypeReference) Category(org.nzbhydra.config.Category) Logger(org.slf4j.Logger) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IdType(org.nzbhydra.mediainfo.InfoProvider.IdType) IOException(java.io.IOException) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) org.nzbhydra.indexers(org.nzbhydra.indexers) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) TimeUnit(java.util.concurrent.TimeUnit) FileDownloadAccessType(org.nzbhydra.config.FileDownloadAccessType) Component(org.springframework.stereotype.Component) ChronoUnit(java.time.temporal.ChronoUnit) ProgressLogger(org.nzbhydra.logging.ProgressLogger) DateTimeFormatter(java.time.format.DateTimeFormatter) MigrationMessageEvent(org.nzbhydra.migration.FromPythonMigration.MigrationMessageEvent) FileDownloadRepository(org.nzbhydra.downloading.FileDownloadRepository) Transactional(org.springframework.transaction.annotation.Transactional) Instant(java.time.Instant) MigrationMessageEvent(org.nzbhydra.migration.FromPythonMigration.MigrationMessageEvent) IdType(org.nzbhydra.mediainfo.InfoProvider.IdType)

Example 9 with Category

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());
    }
}
Also used : AcceptorResult(org.nzbhydra.searching.SearchResultAcceptor.AcceptorResult) UriComponentsBuilder(org.springframework.web.util.UriComponentsBuilder) Setter(lombok.Setter) java.util(java.util) Getter(lombok.Getter) org.nzbhydra.searching(org.nzbhydra.searching) StreamSource(javax.xml.transform.stream.StreamSource) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) SearchModuleType(org.nzbhydra.config.SearchModuleType) Unmarshaller(org.springframework.oxm.Unmarshaller) Subtype(org.nzbhydra.config.Category.Subtype) Strings(com.google.common.base.Strings) Matcher(java.util.regex.Matcher) URI(java.net.URI) Category(org.nzbhydra.config.Category) org.nzbhydra.indexers.exceptions(org.nzbhydra.indexers.exceptions) HasNfo(org.nzbhydra.searching.SearchResultItem.HasNfo) Order(org.springframework.core.annotation.Order) SearchRequest(org.nzbhydra.searching.searchrequests.SearchRequest) Logger(org.slf4j.Logger) IndexerConfig(org.nzbhydra.config.IndexerConfig) InfoProviderException(org.nzbhydra.mediainfo.InfoProviderException) MediaInfo(org.nzbhydra.mediainfo.MediaInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) org.nzbhydra.mapping.newznab.xml(org.nzbhydra.mapping.newznab.xml) IdType(org.nzbhydra.mediainfo.InfoProvider.IdType) IOException(java.io.IOException) Instant(java.time.Instant) IndexerCategoryConfig(org.nzbhydra.config.IndexerCategoryConfig) DownloadType(org.nzbhydra.searching.SearchResultItem.DownloadType) Collectors(java.util.stream.Collectors) ActionAttribute(org.nzbhydra.mapping.newznab.ActionAttribute) Component(org.springframework.stereotype.Component) Stream(java.util.stream.Stream) StringReader(java.io.StringReader) Pattern(java.util.regex.Pattern) Joiner(com.google.common.base.Joiner) Category(org.nzbhydra.config.Category) IndexerCategoryConfig(org.nzbhydra.config.IndexerCategoryConfig)

Example 10 with Category

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));
        }
    }
}
Also used : AcceptorResult(org.nzbhydra.searching.SearchResultAcceptor.AcceptorResult) UriComponentsBuilder(org.springframework.web.util.UriComponentsBuilder) Setter(lombok.Setter) java.util(java.util) Getter(lombok.Getter) org.nzbhydra.searching(org.nzbhydra.searching) StreamSource(javax.xml.transform.stream.StreamSource) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) SearchModuleType(org.nzbhydra.config.SearchModuleType) Unmarshaller(org.springframework.oxm.Unmarshaller) Subtype(org.nzbhydra.config.Category.Subtype) Strings(com.google.common.base.Strings) Matcher(java.util.regex.Matcher) URI(java.net.URI) Category(org.nzbhydra.config.Category) org.nzbhydra.indexers.exceptions(org.nzbhydra.indexers.exceptions) HasNfo(org.nzbhydra.searching.SearchResultItem.HasNfo) Order(org.springframework.core.annotation.Order) SearchRequest(org.nzbhydra.searching.searchrequests.SearchRequest) Logger(org.slf4j.Logger) IndexerConfig(org.nzbhydra.config.IndexerConfig) InfoProviderException(org.nzbhydra.mediainfo.InfoProviderException) MediaInfo(org.nzbhydra.mediainfo.MediaInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) org.nzbhydra.mapping.newznab.xml(org.nzbhydra.mapping.newznab.xml) IdType(org.nzbhydra.mediainfo.InfoProvider.IdType) IOException(java.io.IOException) Instant(java.time.Instant) IndexerCategoryConfig(org.nzbhydra.config.IndexerCategoryConfig) DownloadType(org.nzbhydra.searching.SearchResultItem.DownloadType) Collectors(java.util.stream.Collectors) ActionAttribute(org.nzbhydra.mapping.newznab.ActionAttribute) Component(org.springframework.stereotype.Component) Stream(java.util.stream.Stream) StringReader(java.io.StringReader) Pattern(java.util.regex.Pattern) Joiner(com.google.common.base.Joiner) Matcher(java.util.regex.Matcher)

Aggregations

Category (org.nzbhydra.config.Category)10 IOException (java.io.IOException)4 java.util (java.util)4 Collectors (java.util.stream.Collectors)4 IdType (org.nzbhydra.mediainfo.InfoProvider.IdType)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 Autowired (org.springframework.beans.factory.annotation.Autowired)4 Component (org.springframework.stereotype.Component)4 Instant (java.time.Instant)3 ActionAttribute (org.nzbhydra.mapping.newznab.ActionAttribute)3 org.nzbhydra.searching (org.nzbhydra.searching)3 SearchRequest (org.nzbhydra.searching.searchrequests.SearchRequest)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 Joiner (com.google.common.base.Joiner)2 Strings (com.google.common.base.Strings)2 StringReader (java.io.StringReader)2 URI (java.net.URI)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Matcher (java.util.regex.Matcher)2