diff --git a/src/main/java/ru/mcs/udk/DJVUScanner.java b/src/main/java/ru/mcs/udk/DJVUScanner.java new file mode 100644 index 0000000..d6d0b2a --- /dev/null +++ b/src/main/java/ru/mcs/udk/DJVUScanner.java @@ -0,0 +1,41 @@ +package ru.mcs.udk; + +import net.sourceforge.tess4j.TesseractException; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import static ru.mcs.udk.DocumentUtils.findUDK; + +public class DJVUScanner implements DocumentScanner { + @Override + public void getUDK(File djvuFile) { + String udk = ""; + for (int pageIndex = 0; pageIndex < 6; pageIndex++) { + String outputFile = String.format("temp/page_%d.tiff", pageIndex); + Process process; + try { + process = new ProcessBuilder("ddjvu", + "-format=tiff", + "-quality=90", + "-page=" + pageIndex, + djvuFile.getAbsolutePath(), + outputFile).start(); + int exitCode = process.waitFor(); + if (exitCode == 0) { + BufferedImage image = ImageIO.read(new File(outputFile)); + String text = DocumentUtils.getText(image); + udk = findUDK(text); + } + } catch (InterruptedException | IOException e) { + throw new RuntimeException(e); + } catch (TesseractException e) { + e.printStackTrace(); + } + + } + System.out.printf("%s;%s;%s;%s\n", djvuFile.getPath(), udk, (udk != null && !udk.isEmpty()) ? "ru" : "", ""); + } +} diff --git a/src/main/java/ru/mcs/udk/DjvuScanner.java b/src/main/java/ru/mcs/udk/DjvuScanner.java deleted file mode 100644 index 0df0bd4..0000000 --- a/src/main/java/ru/mcs/udk/DjvuScanner.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.mcs.udk; - -import net.sourceforge.tess4j.TesseractException; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -import static ru.mcs.udk.DocumentUtils.findUDK; - -public class DjvuScanner implements ScannerDocument { - @Override - public void getUDK(File djvuFile) { - String udk = ""; - for (int pageIndex = 0; pageIndex < 6; pageIndex++) { - String outputFile = String.format("temp/page_%d.tiff", pageIndex); - Process process; - try { - process = new ProcessBuilder("ddjvu", - "-format=tiff", - "-quality=90", - "-page=" + pageIndex, - djvuFile.getAbsolutePath(), - outputFile).start(); - int exitCode = process.waitFor(); - if (exitCode == 0) { - BufferedImage image = ImageIO.read(new File(outputFile)); - String text = DocumentUtils.getText(image); - udk = findUDK(text); - } - } catch (InterruptedException | IOException e) { - throw new RuntimeException(e); - } catch (TesseractException e) { - e.printStackTrace(); - } - - } - System.out.printf("%s;%s;%s;%s\n", djvuFile.getPath(), udk, (udk != null && !udk.isEmpty()) ? "ru" : "", ""); - } -} diff --git a/src/main/java/ru/mcs/udk/DocumentScanner.java b/src/main/java/ru/mcs/udk/DocumentScanner.java new file mode 100644 index 0000000..5bdddef --- /dev/null +++ b/src/main/java/ru/mcs/udk/DocumentScanner.java @@ -0,0 +1,9 @@ +package ru.mcs.udk; + +import java.io.File; +import java.io.IOException; + +public interface DocumentScanner { + + void getUDK(File file) throws IOException, InterruptedException; +} diff --git a/src/main/java/ru/mcs/udk/DocumentScannerFactory.java b/src/main/java/ru/mcs/udk/DocumentScannerFactory.java new file mode 100644 index 0000000..1d185f8 --- /dev/null +++ b/src/main/java/ru/mcs/udk/DocumentScannerFactory.java @@ -0,0 +1,13 @@ +package ru.mcs.udk; + +public class DocumentScannerFactory { + public static DocumentScanner getScanner(String filePath) { + if (filePath.toLowerCase().endsWith(".pdf")) { + return new PDFScanner(); + } else if (filePath.toLowerCase().endsWith(".djvu")) { + return new DJVUScanner(); + } else { + throw new IllegalArgumentException("Неподдерживаемый формат файла: " + filePath); + } + } +} diff --git a/src/main/java/ru/mcs/udk/PDFScanner.java b/src/main/java/ru/mcs/udk/PDFScanner.java new file mode 100644 index 0000000..d043d29 --- /dev/null +++ b/src/main/java/ru/mcs/udk/PDFScanner.java @@ -0,0 +1,56 @@ +package ru.mcs.udk; + +import net.sourceforge.tess4j.TesseractException; +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.rendering.PDFRenderer; +import org.apache.pdfbox.text.PDFTextStripper; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Objects; + +import static ru.mcs.udk.DocumentUtils.findUDK; +import static ru.mcs.udk.DocumentUtils.isCyrillic; + +public class PDFScanner implements DocumentScanner { + + @Override + public void getUDK(File file) { + String languageBook = ""; + try (PDDocument document = Loader.loadPDF(file)) { + PDFTextStripper stripper = new PDFTextStripper(); + // Устанавливаем диапазон страниц для анализа (первые три страницы) + stripper.setStartPage(1); + stripper.setEndPage(Math.min(3, document.getNumberOfPages())); + String text = stripper.getText(document); + String udk = findUDK(text); + + languageBook = isCyrillic(file.getName()) ? "ru" : "en"; + + if ((udk == null || udk.isBlank()) && languageBook.equals("ru")) { + udk = getUdkByImage(document); + } + +// System.out.printf("%s;%s;%s;%s\n", file.getPath(), Objects.requireNonNullElse(udk, ""), languageBook, ""); + } catch (IOException | TesseractException e) { + e.printStackTrace(); +// System.out.printf("%s;%s;%s;%s\n", file.getPath(), "", languageBook, e.getMessage()); + } + } + + private static String getUdkByImage(PDDocument document) throws IOException, TesseractException { + PDFRenderer renderer = new PDFRenderer(document); + + for (int pageIndex = 0; pageIndex < 5; pageIndex++) { + BufferedImage image = renderer.renderImageWithDPI(pageIndex, 300); + String text = DocumentUtils.getText(image); + String udk = findUDK(text); + if (udk != null) { + return udk; + } + } + return ""; + } +} diff --git a/src/main/java/ru/mcs/udk/PdfScanner.java b/src/main/java/ru/mcs/udk/PdfScanner.java deleted file mode 100644 index 0a8d6e2..0000000 --- a/src/main/java/ru/mcs/udk/PdfScanner.java +++ /dev/null @@ -1,57 +0,0 @@ -package ru.mcs.udk; - -import net.sourceforge.tess4j.TesseractException; -import org.apache.pdfbox.Loader; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.rendering.PDFRenderer; -import org.apache.pdfbox.text.PDFTextStripper; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.Objects; - -import static ru.mcs.udk.DocumentUtils.findUDK; -import static ru.mcs.udk.DocumentUtils.isCyrillic; - -public class PdfScanner implements ScannerDocument { - - @Override - public void getUDK(File file) { - String languageBook = ""; - try (PDDocument document = Loader.loadPDF(file)) { - PDFTextStripper stripper = new PDFTextStripper(); - // Устанавливаем диапазон страниц для анализа (первые три страницы) - stripper.setStartPage(1); - stripper.setEndPage(Math.min(3, document.getNumberOfPages())); - String text = stripper.getText(document); - String udk = findUDK(text); - - languageBook = isCyrillic(file.getName()) ? "ru" : "en"; - - if ((udk == null || udk.isBlank()) && languageBook.equals("ru")) { - udk = getUdkByImage(document); - } - - System.out.printf("%s;%s;%s;%s\n", file.getPath(), Objects.requireNonNullElse(udk, ""), languageBook, ""); - } catch (IOException e) { - System.out.printf("%s;%s;%s;%s\n", file.getPath(), "", languageBook, e.getMessage()); - } catch (TesseractException e) { - e.printStackTrace(); - } - } - - private static String getUdkByImage(PDDocument document) throws IOException, TesseractException { - PDFRenderer renderer = new PDFRenderer(document); - - for (int pageIndex = 0; pageIndex < 5; pageIndex++) { - BufferedImage image = renderer.renderImageWithDPI(pageIndex, 300); - String text = DocumentUtils.getText(image); - String udk = findUDK(text); - if (udk != null) { - return udk; - } - } - return ""; - } -} diff --git a/src/main/java/ru/mcs/udk/ScannerDocument.java b/src/main/java/ru/mcs/udk/ScannerDocument.java deleted file mode 100644 index cedcb40..0000000 --- a/src/main/java/ru/mcs/udk/ScannerDocument.java +++ /dev/null @@ -1,9 +0,0 @@ -package ru.mcs.udk; - -import java.io.File; -import java.io.IOException; - -public interface ScannerDocument { - - void getUDK(File file) throws IOException, InterruptedException; -} diff --git a/src/main/java/ru/mcs/udk/UDKSearcher.java b/src/main/java/ru/mcs/udk/UDKSearcher.java index 3da80fc..0b82154 100644 --- a/src/main/java/ru/mcs/udk/UDKSearcher.java +++ b/src/main/java/ru/mcs/udk/UDKSearcher.java @@ -2,15 +2,21 @@ import org.apache.commons.cli.*; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class UDKSearcher { - public static void main(String[] args) { + public static void main(String[] args) throws FileNotFoundException { + System.setErr(new PrintStream(new FileOutputStream("error.log"), true, StandardCharsets.UTF_8)); + // Создание опций командной строки Options options = new Options(); options.addOption("path", true, "Путь к папке для поиска файлов"); @@ -45,6 +51,11 @@ System.out.println("Результаты записаны в файл: " + outputFile); } + // проходимся по всем найденым файлам и ищем УДК + findUdk(outputFile); + + + } catch (ParseException e) { System.out.println("Ошибка при разборе аргументов: " + e.getMessage()); printHelp(options); @@ -86,4 +97,60 @@ HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("UDKSearcher", options); } + + private static void findUdk(String outputFile) { + try { + // Чтение всех строк из файла + List lines = Files.readAllLines(Paths.get(outputFile)); + AtomicInteger processedFiles = new AtomicInteger(); // Количество обработанных файлов + int totalFiles = lines.size(); // Общее количество файлов + + + // Обработка каждой строки + List updatedLines = lines.stream() + .map(line -> { + String filePath = line.trim(); // Получаем путь к файлу + File file = new File(filePath); + + // Проверка, существует ли файл + if (file.exists() && file.isFile()) { + processedFiles.getAndIncrement(); + // Засекаем время начала поиска + long startTime = System.currentTimeMillis(); + + // Получаем нужную реализацию сканера + DocumentScanner scanner = DocumentScannerFactory.getScanner(filePath); + // Ищем в УДК номер + try { + scanner.getUDK(file); + } catch (IOException | InterruptedException e) { + System.out.println("Ошибка при работе с файлом: " + e.getMessage()); + } + + // Засекаем время окончания поиска + long endTime = System.currentTimeMillis(); + + double sizeInMB = (double) file.length() / (1024 * 1024); // Размер в мегабайтах + DecimalFormat df = new DecimalFormat("#.##"); // Форматирование до двух знаков после запятой + + // Вычисляем процент завершения + double progress = (double) processedFiles.get() / totalFiles * 100; + System.out.printf("Прогресс: %.2f%%\r", progress); + + return String.format("%s;%s;%s", line, df.format(sizeInMB) + " MB", endTime - startTime); + } else { + return String.format("%s;%s;%s", line, "File not found", ""); // Если файл не найден + } + }) + .collect(Collectors.toList()); + + // Запись обновленных строк обратно в тот же файл + Files.write(Paths.get(outputFile), updatedLines); + + System.out.println("Результат записан в файл: " + outputFile); + + } catch (IOException e) { + System.out.println("Ошибка при работе с файлом: " + e.getMessage()); + } + } } diff --git a/src/main/java/ru/mcs/udk/UdkScannerExecutor.java b/src/main/java/ru/mcs/udk/UdkScannerExecutor.java index 223236a..5f291e1 100644 --- a/src/main/java/ru/mcs/udk/UdkScannerExecutor.java +++ b/src/main/java/ru/mcs/udk/UdkScannerExecutor.java @@ -31,10 +31,10 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { if (file.toAbsolutePath().toString().matches(".*\\.pdf$")) { // Выводим путь и имя файла - PdfScanner pdfScanner = new PdfScanner(); + PDFScanner pdfScanner = new PDFScanner(); pdfScanner.getUDK(file.toFile()); } else if (file.toAbsolutePath().toString().matches(".*\\.djvu$")) { - DjvuScanner djvuScanner = new DjvuScanner(); + DJVUScanner djvuScanner = new DJVUScanner(); djvuScanner.getUDK(file.toFile()); } return FileVisitResult.CONTINUE;