Fix transactional problems and precision loss when transporting search result IDs.

This commit is contained in:
TheOtherP 2024-12-15 09:59:46 +01:00
parent cb3d7f0e41
commit 06f7fa1361
31 changed files with 161 additions and 101 deletions

View File

@ -2,6 +2,7 @@ package org.nzbhydra.downloading;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Sets;
import lombok.Getter;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@ -29,6 +30,7 @@ import org.nzbhydra.web.UrlCalculator;
import org.nzbhydra.webaccess.HydraOkHttp3ClientHttpRequestFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
@ -81,7 +83,10 @@ public class FileHandler {
protected UrlCalculator urlCalculator;
@Autowired
private IndexerSpecificDownloadExceptions indexerSpecificDownloadExceptions;
@Autowired
private BeanFactory beanFactory;
@Getter
private final Set<File> temporaryZipFiles = new HashSet<>();
@Autowired
private TempFileProvider tempFileProvider;
@ -91,7 +96,7 @@ public class FileHandler {
final IndexerConfig indexerConfig = configProvider.getIndexerByName(searchResult.getIndexer().getName());
FileDownloadAccessType fileDownloadAccessType = indexerSpecificDownloadExceptions.getAccessTypeForIndexer(indexerConfig, configProvider.getBaseConfig().getDownloading().getNzbAccessType());
return getFileByResult(fileDownloadAccessType, accessSource, searchResult);
return beanFactory.getBean(FileHandler.class).getFileByResult(fileDownloadAccessType, accessSource, searchResult);
}
@Transactional
@ -123,10 +128,10 @@ public class FileHandler {
private DownloadResult getFileByResult(FileDownloadAccessType fileDownloadAccessType, SearchSource accessSource, SearchResultEntity result, Set<SearchResultEntity> alreadyTriedDownloading) {
logger.info("{} download request for \"{}\" from indexer {}", fileDownloadAccessType, result.getTitle(), result.getIndexer().getName());
if (fileDownloadAccessType == FileDownloadAccessType.REDIRECT) {
return handleRedirect(accessSource, result, null);
return beanFactory.getBean(FileHandler.class).handleRedirect(accessSource, result, null);
} else {
try {
final DownloadResult downloadResult = handleContentDownload(accessSource, result);
final DownloadResult downloadResult = beanFactory.getBean(FileHandler.class).handleContentDownload(accessSource, result);
if (downloadResult.isSuccessful()) {
return downloadResult;
}
@ -137,8 +142,8 @@ public class FileHandler {
alreadyTriedDownloading.add(result);
final Set<SearchResultEntity> similarResults = searchResultRepository.findAllByTitleLikeIgnoreCase(result.getTitle().replaceAll("[ .\\-_]", "_"));
final Optional<SearchResultEntity> similarResult = similarResults.stream()
.filter(x -> x != result && !alreadyTriedDownloading.contains(x))
.findFirst();
.filter(x -> x != result && !alreadyTriedDownloading.contains(x))
.findFirst();
if (similarResult.isPresent()) {
logger.info("Falling back from failed download to similar result {}", similarResult.get());
return getFileByResult(fileDownloadAccessType, accessSource, similarResult.get(), alreadyTriedDownloading);
@ -194,7 +199,7 @@ public class FileHandler {
@Transactional
public DownloadResult handleRedirect(SearchSource accessSource, SearchResultEntity result, String actualUrl) {
logger.debug("Redirecting to " + result.getLink());
logger.debug("Redirecting to {}", result.getLink());
FileDownloadEntity downloadEntity = new FileDownloadEntity(result, FileDownloadAccessType.REDIRECT, accessSource, FileDownloadStatus.REQUESTED, null);
if (configProvider.getBaseConfig().getMain().isKeepHistory()) {
downloadRepository.save(downloadEntity);
@ -253,7 +258,7 @@ public class FileHandler {
final IndexerConfig indexerConfig = configProvider.getIndexerByName(searchResult.getIndexer().getName());
final FileDownloadAccessType accessType = indexerSpecificDownloadExceptions.getAccessTypeForIndexer(indexerConfig, FileDownloadAccessType.PROXY);
if (accessType == FileDownloadAccessType.PROXY) {
result = getFileByGuid(guid, FileDownloadAccessType.PROXY, SearchSource.INTERNAL);
result = beanFactory.getBean(FileHandler.class).getFileByGuid(guid, FileDownloadAccessType.PROXY, SearchSource.INTERNAL);
} else {
logger.info("Can't download NZB from indexer {} because it forbids direct access from NZBHydra", indexerConfig.getName());
failedIds.add(guid);
@ -275,7 +280,7 @@ public class FileHandler {
files.add(tempFile);
successfulIds.add(guid);
} catch (IOException e) {
logger.error("Unable to write file content to temporary file: " + e.getMessage());
logger.error("Unable to write file content to temporary file: {}", e.getMessage());
failedIds.add(guid);
}
}
@ -357,7 +362,7 @@ public class FileHandler {
public NfoResult getNfo(Long searchResultId) {
Optional<SearchResultEntity> optionalResult = searchResultRepository.findById(searchResultId);
if (optionalResult.isEmpty()) {
logger.error("Download request with invalid/outdated search result ID " + searchResultId);
logger.error("Download request with invalid/outdated search result ID {}", searchResultId);
throw new RuntimeException("Download request with invalid/outdated search result ID " + searchResultId);
}
SearchResultEntity result = optionalResult.get();
@ -432,10 +437,6 @@ public class FileHandler {
return GenericResponse.ok();
}
public Set<File> getTemporaryZipFiles() {
return temporaryZipFiles;
}
private static class NzbsDownload {
private final List<File> files;
private final List<Long> successfulIds;

View File

@ -224,7 +224,6 @@ public class Torbox extends Downloader {
UsenetListResponse body = response.getBody();
if (response.getStatusCode().is2xxSuccessful()) {
lastUpdate = Instant.now();
lastTorboxDownloads.clear();
lastTorboxDownloads.addAll(body.getData());

View File

@ -30,6 +30,7 @@ import org.nzbhydra.searching.db.SearchResultEntity;
import org.nzbhydra.searching.db.SearchResultRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -53,6 +54,8 @@ public class TorrentFileHandler {
@Autowired
private FileHandler fileHandler;
@Autowired
private BeanFactory beanFactory;
@Autowired
protected ConfigProvider configProvider;
@Autowired
private SearchResultRepository searchResultRepository;
@ -85,7 +88,7 @@ public class TorrentFileHandler {
DownloadResult result;
boolean successful = false;
try {
result = getTorrentByGuid(guid, FileDownloadAccessType.PROXY, SearchSource.INTERNAL);
result = beanFactory.getBean(TorrentFileHandler.class).getTorrentByGuid(guid, FileDownloadAccessType.PROXY, SearchSource.INTERNAL);
} catch (InvalidSearchResultIdException e) {
logger.error("Unable to find result with ID {}", guid);
failedIds.add(guid);

View File

@ -38,8 +38,8 @@ public class Anizb extends Indexer<NewznabXmlRoot> {
private static final Logger logger = LoggerFactory.getLogger(Anizb.class);
public Anizb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public Anizb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}

View File

@ -72,8 +72,8 @@ public class Binsearch extends Indexer<String> {
.withDelay(Duration.ofMillis(500))
.withMaxRetries(2).build();
public Binsearch(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public Binsearch(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
static Clock clock = Clock.systemUTC();

View File

@ -35,8 +35,8 @@ import java.util.Collections;
@Component
public class DevIndexer extends Newznab {
public DevIndexer(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
public DevIndexer(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
protected Xml getAndStoreResultToDatabase(URI uri, IndexerApiAccessType apiAccessType) throws IndexerAccessException {

View File

@ -29,8 +29,8 @@ public class DogNzb extends Newznab {
private static final Logger logger = LoggerFactory.getLogger(DogNzb.class);
public DogNzb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
public DogNzb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
protected void completeIndexerSearchResult(Xml response, IndexerSearchResult indexerSearchResult, AcceptorResult acceptorResult, SearchRequest searchRequest, int offset, Integer limit) {

View File

@ -2,7 +2,6 @@ package org.nzbhydra.indexers;
import com.google.common.base.Objects;
import com.google.common.base.Stopwatch;
import jakarta.persistence.EntityExistsException;
import joptsimple.internal.Strings;
import org.nzbhydra.config.BaseConfigHandler;
import org.nzbhydra.config.ConfigChangedEvent;
@ -24,8 +23,6 @@ import org.nzbhydra.searching.CategoryProvider;
import org.nzbhydra.searching.CustomQueryAndTitleMappingHandler;
import org.nzbhydra.searching.SearchResultAcceptor;
import org.nzbhydra.searching.SearchResultAcceptor.AcceptorResult;
import org.nzbhydra.searching.SearchResultIdCalculator;
import org.nzbhydra.searching.db.SearchResultEntity;
import org.nzbhydra.searching.db.SearchResultRepository;
import org.nzbhydra.searching.dtoseventsenums.FallbackSearchInitiatedEvent;
import org.nzbhydra.searching.dtoseventsenums.IndexerSearchFinishedEvent;
@ -42,7 +39,6 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@ -50,13 +46,10 @@ import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -107,13 +100,15 @@ public abstract class Indexer<T> {
private BaseConfigHandler baseConfigHandler;
protected AutowireCapableBeanFactory beanFactory;
private IndexerSearchResultPersistor searchResultPersistor;
protected Indexer() {
}
public Indexer(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
public Indexer(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor persistor) {
this.configProvider = configProvider;
this.indexerRepository = indexerRepository;
this.searchResultRepository = searchResultRepository;
@ -127,6 +122,7 @@ public abstract class Indexer<T> {
this.queryGenerator = queryGenerator;
this.titleMapping = titleMapping;
this.baseConfigHandler = baseConfigHandler;
this.searchResultPersistor = persistor;
}
@ -280,39 +276,11 @@ public abstract class Indexer<T> {
return query;
}
@Transactional
protected List<SearchResultItem> persistSearchResults(List<SearchResultItem> searchResultItems, IndexerSearchResult indexerSearchResult) {
Stopwatch stopwatch = Stopwatch.createStarted();
synchronized (dbLock) { //Locking per indexer prevents multiple threads trying to save the same "new" results to the database
ArrayList<SearchResultEntity> searchResultEntities = new ArrayList<>();
Set<Long> alreadySavedIds = searchResultRepository.findAllIdsByIdIn(searchResultItems.stream().map(SearchResultIdCalculator::calculateSearchResultId).collect(Collectors.toList()));
for (SearchResultItem item : searchResultItems) {
long guid = SearchResultIdCalculator.calculateSearchResultId(item);
if (!alreadySavedIds.contains(guid)) {
SearchResultEntity searchResultEntity = new SearchResultEntity();
//Set all entity relevant data
searchResultEntity.setIndexer(indexer);
searchResultEntity.setTitle(item.getTitle());
searchResultEntity.setLink(item.getLink());
searchResultEntity.setDetails(item.getDetails());
searchResultEntity.setIndexerGuid(item.getIndexerGuid());
searchResultEntity.setFirstFound(Instant.now());
searchResultEntity.setDownloadType(item.getDownloadType());
searchResultEntity.setPubDate(item.getPubDate());
searchResultEntities.add(searchResultEntity);
}
//LATER Unify guid and searchResultId which are the same
item.setGuid(guid);
item.setSearchResultId(guid);
}
debug("Found {} results which were already in the database and {} new ones", alreadySavedIds.size(), searchResultEntities.size());
try {
searchResultRepository.saveAll(searchResultEntities);
indexerSearchResult.setSearchResultEntities(new HashSet<>(searchResultEntities));
} catch (EntityExistsException e) {
error("Unable to save the search results to the database", e);
}
searchResultPersistor.persistSearchResults(this, searchResultItems, indexerSearchResult);
}
getLogger().debug(LoggingMarkers.PERFORMANCE, "Persisting {} search results took {}ms", searchResultItems.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS));

View File

@ -0,0 +1,81 @@
/*
* (C) Copyright 2024 TheOtherP (theotherp@posteo.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nzbhydra.indexers;
import jakarta.persistence.EntityExistsException;
import lombok.extern.slf4j.Slf4j;
import org.nzbhydra.searching.SearchResultIdCalculator;
import org.nzbhydra.searching.db.SearchResultEntity;
import org.nzbhydra.searching.db.SearchResultRepository;
import org.nzbhydra.searching.dtoseventsenums.IndexerSearchResult;
import org.nzbhydra.searching.dtoseventsenums.SearchResultItem;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Component
@Slf4j
public class IndexerSearchResultPersistor {
private final SearchResultRepository searchResultRepository;
public IndexerSearchResultPersistor(SearchResultRepository searchResultRepository) {
this.searchResultRepository = searchResultRepository;
}
@Transactional
public List<SearchResultItem> persistSearchResults(Indexer<?> indexer, List<SearchResultItem> searchResultItems, IndexerSearchResult indexerSearchResult) {
ArrayList<SearchResultEntity> searchResultEntities = new ArrayList<>();
Set<Long> alreadySavedIds = searchResultRepository.findAllIdsByIdIn(searchResultItems.stream().map(SearchResultIdCalculator::calculateSearchResultId).collect(Collectors.toList()));
for (SearchResultItem item : searchResultItems) {
long guid = SearchResultIdCalculator.calculateSearchResultId(item);
if (!alreadySavedIds.contains(guid)) {
SearchResultEntity searchResultEntity = new SearchResultEntity();
//Set all entity relevant data
searchResultEntity.setIndexer(indexer.getIndexerEntity());
searchResultEntity.setTitle(item.getTitle());
searchResultEntity.setLink(item.getLink());
searchResultEntity.setDetails(item.getDetails());
searchResultEntity.setIndexerGuid(item.getIndexerGuid());
searchResultEntity.setFirstFound(Instant.now());
searchResultEntity.setDownloadType(item.getDownloadType());
searchResultEntity.setPubDate(item.getPubDate());
searchResultEntities.add(searchResultEntity);
}
//LATER Unify guid and searchResultId which are the same
item.setGuid(guid);
item.setSearchResultId(guid);
}
indexer.debug("Found {} results which were already in the database and {} new ones", alreadySavedIds.size(), searchResultEntities.size());
try {
searchResultRepository.saveAll(searchResultEntities);
indexerSearchResult.setSearchResultEntities(new HashSet<>(searchResultEntities));
} catch (EntityExistsException e) {
indexer.error("Unable to save the search results to the database", e);
}
return searchResultItems;
}
}

View File

@ -117,8 +117,8 @@ public class Newznab extends Indexer<Xml> {
private final ConcurrentHashMap<Integer, Category> idToCategory = new ConcurrentHashMap<>();
public Newznab(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public Newznab(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
this.unmarshaller = unmarshaller;
this.indexerStatusRepository = indexerStatusRepository;
this.baseConfigHandler = baseConfigHandler;

View File

@ -24,8 +24,8 @@ import java.util.Arrays;
public class NzbGeek extends Newznab {
public NzbGeek(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
public NzbGeek(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
@Override

View File

@ -43,8 +43,8 @@ public class NzbIndex extends Indexer<NewznabXmlRoot> {
private static final Pattern GUID_PATTERN = Pattern.compile(".*/download/(\\d+).*", Pattern.DOTALL);
private static final Pattern NFO_PATTERN = Pattern.compile(".*<pre id=\"nfo0\">(.*)</pre>.*", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
public NzbIndex(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public NzbIndex(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}

View File

@ -43,8 +43,8 @@ public class NzbIndexApi extends Indexer<NzbIndexRoot> {
private static final Pattern NFO_PATTERN = Pattern.compile(".*<pre id=\"nfo0\">(.*)</pre>.*", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
public static final int PAGE_SIZE = 250;
public NzbIndexApi(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public NzbIndexApi(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}

View File

@ -43,8 +43,8 @@ public class NzbIndexBeta extends Indexer<NewznabXmlRoot> {
private static final Pattern GUID_PATTERN = Pattern.compile(".*/download/([\\d\\-a-f]+).*", Pattern.DOTALL);
private static final Pattern NFO_PATTERN = Pattern.compile(".*<pre id=\"nfo0\">(.*)</pre>.*", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
public NzbIndexBeta(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public NzbIndexBeta(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}

View File

@ -63,8 +63,8 @@ public class NzbKing extends Indexer<String> {
.withDelay(Duration.ofMillis(500))
.withMaxRetries(2).build();
public NzbKing(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
public NzbKing(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
static Clock clock = Clock.systemUTC();

View File

@ -30,8 +30,8 @@ public class WtfNzb extends Newznab {
private static final Logger logger = LoggerFactory.getLogger(WtfNzb.class);
public WtfNzb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
public WtfNzb(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
@Override

View File

@ -28,6 +28,7 @@ import org.nzbhydra.indexers.IndexerApiAccessEntityShortRepository;
import org.nzbhydra.indexers.IndexerApiAccessRepository;
import org.nzbhydra.indexers.IndexerHandlingStrategy;
import org.nzbhydra.indexers.IndexerRepository;
import org.nzbhydra.indexers.IndexerSearchResultPersistor;
import org.nzbhydra.indexers.IndexerWebAccess;
import org.nzbhydra.indexers.Newznab;
import org.nzbhydra.indexers.QueryGenerator;
@ -68,8 +69,8 @@ public class Torznab extends Newznab {
private static final Logger logger = LoggerFactory.getLogger(Torznab.class);
public Torznab(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
public Torznab(ConfigProvider configProvider, IndexerRepository indexerRepository, SearchResultRepository searchResultRepository, IndexerApiAccessRepository indexerApiAccessRepository, IndexerApiAccessEntityShortRepository indexerApiAccessShortRepository, IndexerLimitRepository indexerStatusRepository, IndexerWebAccess indexerWebAccess, SearchResultAcceptor resultAcceptor, CategoryProvider categoryProvider, InfoProvider infoProvider, ApplicationEventPublisher eventPublisher, QueryGenerator queryGenerator, CustomQueryAndTitleMappingHandler titleMapping, Unmarshaller unmarshaller, BaseConfigHandler baseConfigHandler, IndexerSearchResultPersistor searchResultPersistor) {
super(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
protected SearchResultItem createSearchResultItem(NewznabXmlItem item) throws NzbHydraException {

View File

@ -61,41 +61,43 @@ public class IndexerInstantiator {
private Unmarshaller unmarshaller;
@Autowired
private BaseConfigHandler baseConfigHandler;
@Autowired
private IndexerSearchResultPersistor searchResultPersistor;
public Indexer instantiateIndexer(String name) {
switch (name) {
case "ANIZB" -> {
return new Anizb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new Anizb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "BINSEARCH" -> {
return new Binsearch(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new Binsearch(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "DOGNZB" -> {
return new DogNzb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
return new DogNzb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
case "NEWZNAB" -> {
return new Newznab(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
return new Newznab(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
case "WTFNZB" -> {
return new WtfNzb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
return new WtfNzb(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
case "NZBINDEX" -> {
return new NzbIndex(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new NzbIndex(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "NZBINDEX_BETA" -> {
return new NzbIndexBeta(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new NzbIndexBeta(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "NZBINDEX_API" -> {
return new NzbIndexApi(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new NzbIndexApi(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "NZBGEEK" -> {
return new NzbGeek(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
return new NzbGeek(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
case "NZBKING" -> {
return new NzbKing(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler);
return new NzbKing(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, baseConfigHandler, searchResultPersistor);
}
case "TORZNAB" -> {
return new Torznab(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler);
return new Torznab(configProvider, indexerRepository, searchResultRepository, indexerApiAccessRepository, indexerApiAccessShortRepository, indexerStatusRepository, indexerWebAccess, resultAcceptor, categoryProvider, infoProvider, eventPublisher, queryGenerator, titleMapping, unmarshaller, baseConfigHandler, searchResultPersistor);
}
}
throw new RuntimeException("Unable to instantiate " + name);

View File

@ -8,6 +8,8 @@
text: "Remove unneeded file from generic release which increased the size of the architect by a whopping 100MB."
- type: "fix"
text: "Only show option for primary downloader if multiple downloaders are enabled."
- type: "fix"
text: "Sometimes downloads from the search result history could not be downloaded again."
final: true
- version: "v7.10.2"
date: "2024-12-04"

View File

@ -32,7 +32,8 @@ public class AnizbTest {
private QueryGenerator queryGeneratorMock;
@InjectMocks
private Anizb testee = new Anizb(configProviderMock, null, null, null, null, null, null, null, null, null, null, queryGeneratorMock, null, null);
private Anizb testee =
new Anizb(configProviderMock, null, null, null, null, null, null, null, null, null, null, queryGeneratorMock, null, null, null);
@BeforeEach
public void setUp() throws Exception {

View File

@ -52,7 +52,7 @@ public class BinsearchTest {
@InjectMocks
private Binsearch testee = new Binsearch(configProviderMock, null, null, null, null, null,
null, null, categoryProviderMock, null, null, queryGeneratorMock, null, null);
null, null, categoryProviderMock, null, null, queryGeneratorMock, null, null, null);
@BeforeEach
public void setUp() throws Exception {

View File

@ -26,7 +26,7 @@ import java.net.URI;
public class DevIndexerTest {
@InjectMocks
private DevIndexer testee = new DevIndexer(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private DevIndexer testee = new DevIndexer(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
@Test
void testGeneration() throws Exception {

View File

@ -44,8 +44,8 @@ import java.util.concurrent.TimeUnit;
@EnabledIfEnvironmentVariable(named = "DEV_ENV_SET", matches = "true")
public class IndexerIdiocyCheckTest {
private final NzbGeek nzbGeek = new NzbGeek(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private final DogNzb dogNzb = new DogNzb(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private final NzbGeek nzbGeek = new NzbGeek(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private final DogNzb dogNzb = new DogNzb(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
protected Unmarshaller unmarshaller = new WebConfiguration().marshaller();

View File

@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class NzbGeekTest {
@InjectMocks
private NzbGeek testee = new NzbGeek(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private NzbGeek testee = new NzbGeek(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
@Test

View File

@ -30,7 +30,7 @@ public class NzbIndexBetaTest {
private CategoryProvider categoryProviderMock;
@InjectMocks
private NzbIndexBeta testee = new NzbIndexBeta(null, null, null, null, null, null, null, null, categoryProviderMock, null, null, null, null, null);
private NzbIndexBeta testee = new NzbIndexBeta(null, null, null, null, null, null, null, null, categoryProviderMock, null, null, null, null, null, null);
@BeforeEach
public void setUp() throws Exception {

View File

@ -30,7 +30,7 @@ public class NzbIndexTest {
private CategoryProvider categoryProviderMock;
@InjectMocks
private NzbIndex testee = new NzbIndex(null, null, null, null, null, null, null, null, categoryProviderMock, null, null, null, null, null);
private NzbIndex testee = new NzbIndex(null, null, null, null, null, null, null, null, categoryProviderMock, null, null, null, null, null, null);
@BeforeEach
public void setUp() throws Exception {

View File

@ -53,7 +53,7 @@ public class NzbKingTest {
@InjectMocks
private NzbKing testee = new NzbKing(configProviderMock, null, null, null, null, null,
null, null, categoryProviderMock, null, null, queryGeneratorMock, null, null);
null, null, categoryProviderMock, null, null, queryGeneratorMock, null, null, null);
@BeforeEach
public void setUp() throws Exception {

View File

@ -103,7 +103,7 @@ public class TorznabTest {
private QueryGenerator queryGeneratorMock;
@InjectMocks
private Torznab testee = new Torznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
private Torznab testee = new Torznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
@BeforeEach

View File

@ -151,7 +151,7 @@ public class DuplicateDetectorTest {
item.setGroup(group);
item.setSize(10000L);
item.setLink("" + new Random().nextInt());
Newznab indexer = new Newznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
Newznab indexer = new Newznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
IndexerConfig config = new IndexerConfig();
config.setName(indexerName);
IndexerEntity indexerEntity = new IndexerEntity();

View File

@ -268,7 +268,7 @@ public class SearchResultAcceptorTest {
@Test
void shouldCheckForCategoryDisabledForIndexer() {
Indexer indexer = new Newznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
Indexer indexer = new Newznab(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
indexer.initialize(indexerConfig, new IndexerEntity());
item.setIndexer(indexer);

View File

@ -16,6 +16,8 @@
package org.nzbhydra.searching.db;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -32,7 +34,7 @@ import java.time.Instant;
@NoArgsConstructor
public class SearchResultEntityTO {
@JsonSerialize(using = ToStringSerializer.class)
private long id;
private IndexerEntityTO indexer;
private Instant firstFound;