package ru.mcs.udk;
import net.sourceforge.tess4j.TesseractException;
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.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PdfScanner {
public static void main(String[] args) throws FileNotFoundException {
if (args.length == 0) {
System.out.println("Пожалуйста, укажите путь к папке.");
return;
}
String directoryPath = args[0];
Path startDir = Paths.get(directoryPath);
if (!Files.exists(startDir) || !Files.isDirectory(startDir)) {
System.out.println("Указанный путь не существует или не является папкой.");
return;
}
System.setOut(new PrintStream(new FileOutputStream("book-list.csv"), true, StandardCharsets.UTF_8));
try {
Files.walkFileTree(startDir, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toAbsolutePath().toString().matches(".*\\.pdf$")) {
// Выводим путь и имя файла
getUdk(file.toAbsolutePath());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
// Обрабатываем ошибки доступа к файлам
System.err.println("Ошибка доступа к файлу: " + file.toAbsolutePath() + " - " + exc.getMessage());
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public static void getUdk(Path filePath) {
File file = filePath.toFile();
String languageBook = "";
try (PDDocument document = PDDocument.load(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(String.valueOf(filePath.getFileName())) ? "ru" : "en";
if ((udk == null || udk.isBlank()) && languageBook.equals("ru")) {
udk = getUdkByImage(document);
}
System.out.printf("%s;%s;%s;%s\n", filePath.toAbsolutePath(), Objects.requireNonNullElse(udk, ""), languageBook, "");
} catch (IOException e) {
System.out.printf("%s;%s;%s;%s\n", filePath.toAbsolutePath(), Objects.requireNonNullElse("", ""), 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 = OCRUtils.getText(image);
String udk = findUDK(text);
if (udk != null) {
return udk;
}
}
return "";
}
public static String findUDK(String text) {
// Регулярное выражение для поиска УДК
Pattern pattern = Pattern.compile("[Уу]\\s*[Дд]\\s*[Кк]\\s*([0-9.]+)");
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
public static boolean isCyrillic(String fileName) {
String regex = ".*[\\p{IsCyrillic}]{3,}.*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(fileName);
return matcher.matches();
}
}