diff --git a/pom.xml b/pom.xml index 798db09..b8aadc4 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ resteasy-client 3.5.0.Final - + javax.xml jaxb-api diff --git a/src/main/java/tv/mangrana/config/ConfigFileLoader.java b/src/main/java/tv/mangrana/config/ConfigFileLoader.java index ae3162c..7249227 100644 --- a/src/main/java/tv/mangrana/config/ConfigFileLoader.java +++ b/src/main/java/tv/mangrana/config/ConfigFileLoader.java @@ -18,7 +18,6 @@ public class ConfigFileLoader extends CommonConfigFileLoader torrentFiles = resolveTorrentFiles(); - List sonarFiles = resolveSonarrFiles(); + System.out.printf("%nfixing: %s%n" , torrentTitle); + List torrentFiles = getVideoFilesFrom(torrentPath); + List sonarFiles = getVideoFilesFrom(seasonPath); List filesToCopy = missingFilesDetector.getMissingFilesAtDestination(torrentFiles, sonarFiles); filesToCopy.forEach(this::copy); } - private List resolveTorrentFiles() throws IOException { - return getVideoFilesFrom(torrentPath); - } - - private List resolveSonarrFiles() throws IOException { - seasonPath = seriePath.resolve(getSeasonFolder()); - return getVideoFilesFrom(seasonPath); - } - - private String getSeasonFolder() { - try { - return StringCaptor.getSeasonFolderNameFromSeason(torrentPath.getFileName().toString()); - } catch (IncorrectWorkingReferencesException e) { - throw new RuntimeException(e); - } - } - private List getVideoFilesFrom(Path path) throws IOException { System.out.println("going to explore "+path); - try (var pathWalk = Files.walk(path, 3)) { - return pathWalk - .filter(p -> p.toFile().isFile()) - .filter(p -> p.toFile().length() > MINIMUM_FILE_SIZE_TO_BE_CONSIDERED_A_VIDEO) - .collect(Collectors.toList()); + try (var pathsWalk = Files.walk(path, 3)) { + return pathsWalk + .filter(this::isFile) + .filter(this::isAVideo) + .toList(); } } + private boolean isFile(Path path) { + return path.toFile().isFile(); + } + private boolean isAVideo(Path path) { + return path.toFile().length() > MINIMUM_FILE_SIZE_TO_BE_CONSIDERED_A_VIDEO; + } private void copy(Path fileToCopy) { Path target = seasonPath.resolve(fileToCopy.getFileName()); System.out.println("** going to hardlink file to "+target); fileCopier.hardLink(fileToCopy, target); } + + static class SeasonFolderUnretrievable extends RuntimeException {} } diff --git a/src/main/java/tv/mangrana/worker/FileCopier.java b/src/main/java/tv/mangrana/worker/FileCopier.java index d1e0d95..d684467 100644 --- a/src/main/java/tv/mangrana/worker/FileCopier.java +++ b/src/main/java/tv/mangrana/worker/FileCopier.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -public class FileCopier { +class FileCopier { void hardLink(Path source, Path destination) { try { Files.createLink(destination, source); @@ -15,10 +15,3 @@ public class FileCopier { } } } - -class ProjectPath { - static Path of(String path) { - String projectPath = System.getProperty("user.dir"); - return Path.of(projectPath + path); - } -} diff --git a/src/main/java/tv/mangrana/worker/MainWorker.java b/src/main/java/tv/mangrana/worker/MainWorker.java index 32cd947..68abb2c 100644 --- a/src/main/java/tv/mangrana/worker/MainWorker.java +++ b/src/main/java/tv/mangrana/worker/MainWorker.java @@ -13,7 +13,7 @@ public class MainWorker { worker.work(); } - public MainWorker() throws IncorrectWorkingReferencesException { + private MainWorker() throws IncorrectWorkingReferencesException { var configLoader = ConfigFileLoader.getLoader(); Sonarr.initService(configLoader); queueFixer = new QueueFixer(); diff --git a/src/main/java/tv/mangrana/worker/MissingFilesDetector.java b/src/main/java/tv/mangrana/worker/MissingFilesDetector.java index cbcf583..f267f28 100644 --- a/src/main/java/tv/mangrana/worker/MissingFilesDetector.java +++ b/src/main/java/tv/mangrana/worker/MissingFilesDetector.java @@ -5,10 +5,10 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -public class MissingFilesDetector { +class MissingFilesDetector { private Map> sonarrFilesByLength; - private Map> torrentFileLengths; + private Map> torrentFilesByLength; List getMissingFilesAtDestination(List torrentFiles, List sonarrFiles) { System.out.printf("going to compare %d torrent files with %d sonar files%n", @@ -19,8 +19,8 @@ public class MissingFilesDetector { } private void digestTorrentFiles(List torrentFiles) { - torrentFileLengths = getFileLengthsMapFrom(torrentFiles); - throwIfDuplicatedSizes(torrentFileLengths); + torrentFilesByLength = getFileLengthsMapFrom(torrentFiles); + throwIfDuplicatedSizes(torrentFilesByLength); } private void digestSonarrFiles(List sonarrFiles) { @@ -28,35 +28,8 @@ public class MissingFilesDetector { throwIfDuplicatedSizes(sonarrFilesByLength); } - Map> getFileLengthsMapFrom(List files) { - return files.stream() - .collect(Collectors.groupingBy(p -> p.toFile().length())); - } - - private void throwIfDuplicatedSizes(Map> torrentFileLengths) { - if (hasFilesWithSameSize(torrentFileLengths)) - throw new InsecureScenario(); - } - - boolean hasFilesWithSameSize(Map> torrentFileLengths) { - return torrentFileLengths - .values() - .stream() - .anyMatch(this::hasMultipleElements); - } - - boolean hasMultipleElements(List paths) { - if (paths.size() > 1) { - var sampleFile = paths.get(0).toFile(); - System.out.printf("!!! There is more than one file with the same size of %d. Name: %s %n", - sampleFile.length(), sampleFile.getName()); - return true; - } - return false; - } - private List resolveMissingFiles() { - return torrentFileLengths.entrySet() + return torrentFilesByLength.entrySet() .stream() .filter(this::missingAtDestination) .map(Map.Entry::getValue) @@ -64,6 +37,33 @@ public class MissingFilesDetector { .toList(); } + Map> getFileLengthsMapFrom(List files) { + return files.stream() + .collect(Collectors.groupingBy(p -> p.toFile().length())); + } + + private void throwIfDuplicatedSizes(Map> filesByLength) { + if (hasFilesWithSameSize(filesByLength)) + throw new InsecureScenario(); + } + + boolean hasFilesWithSameSize(Map> filesByLength) { + return filesByLength + .values() + .stream() + .anyMatch(this::hasMultipleElements); + } + + boolean hasMultipleElements(List elements) { + if (elements.size() > 1) { + var sampleFile = elements.get(0).toFile(); + System.out.printf("!!! There is more than one file with the same size of %d. Name: %s %n", + sampleFile.length(), sampleFile.getName()); + return true; + } + return false; + } + private boolean missingAtDestination(Map.Entry> torrentFileEntry) { return !sonarrFilesByLength.containsKey(torrentFileEntry.getKey()); } diff --git a/src/main/java/tv/mangrana/worker/QueueFixer.java b/src/main/java/tv/mangrana/worker/QueueFixer.java index 601fdeb..ae79599 100644 --- a/src/main/java/tv/mangrana/worker/QueueFixer.java +++ b/src/main/java/tv/mangrana/worker/QueueFixer.java @@ -9,22 +9,22 @@ import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.List; -import java.util.Map; public class QueueFixer { final static String IMPORT_FAILURE_BECAUSE_MATCHED_BY_ID = "Found matching series via grab history, but release was matched to series by ID. Automatic import is not possible. See the FAQ for details."; + private final SonarrApiGateway sonarrApiGateway; - private final FailedImportFixer.Factory failedImportFixerFactory; + private final FailedImportFixer.Factory fixerFactory; QueueFixer() { sonarrApiGateway = Sonarr.api(); - failedImportFixerFactory = FailedImportFixer.factory(); + fixerFactory = FailedImportFixer.factory(); } void fix() { List sonarQueue = retrieveQueueRecordsFromSonarr(); - Collection records = deduplicate(sonarQueue); - List recordsToFix = filterFailedImportsOfIdProblem(records); + var distinctRecords = deduplicate(sonarQueue); + var recordsToFix = filterFailedImportsOfIdProblem(distinctRecords); recordsToFix.forEach(this::try2FixFailedImport); } @@ -33,9 +33,9 @@ public class QueueFixer { } private Collection deduplicate(List repetitiveRecords) { - Map recordsByTitle = new HashMap<>(); - repetitiveRecords.forEach(record -> - recordsByTitle.putIfAbsent(record.getTitle(), record)); + var recordsByTitle = new HashMap(); + for (var record : repetitiveRecords) + recordsByTitle.putIfAbsent(record.getTitle(), record); return recordsByTitle.values(); } @@ -45,19 +45,13 @@ public class QueueFixer { .toList(); } - private boolean recordsWithImportFailureBecauseIdMatching(Record record) { - return record.getStatusMessages().stream() - .flatMap(status -> status.getMessages().stream()) - .anyMatch(IMPORT_FAILURE_BECAUSE_MATCHED_BY_ID::equals); - } - private void try2FixFailedImport(Record record) { try { var seriesId = record.getSeriesId(); - SonarrSerie serie = getSerieFromSonarr(seriesId); + SonarrSerie serie = sonarrApiGateway.getSerieById(seriesId); if (serie == null) return; - failedImportFixerFactory + fixerFactory .newFixerFor(record, serie) .fix(); } catch (IOException e) { @@ -66,8 +60,10 @@ public class QueueFixer { } } - private SonarrSerie getSerieFromSonarr(Integer seriesId) { - return sonarrApiGateway.getSerieById(seriesId); + private boolean recordsWithImportFailureBecauseIdMatching(Record record) { + return record.getStatusMessages().stream() + .flatMap(status -> status.getMessages().stream()) + .anyMatch(IMPORT_FAILURE_BECAUSE_MATCHED_BY_ID::equals); } }