186 lines
7.6 KiB
PHP
186 lines
7.6 KiB
PHP
|
|
<?php
|
|||
|
|
define('SCAN_DIR', 'scanpdf');
|
|||
|
|
define('LOG_FILE', 'logs/CheckPDF.log');
|
|||
|
|
define('OPENAI_API_KEY', 'sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'); // Замените на свой ключ
|
|||
|
|
|
|||
|
|
//define('OPENAI_API_URL', 'https://api.proxyapi.ru/deepseek/chat/completions');
|
|||
|
|
//define('OPENAI_VISION_URL', 'https://api.proxyapi.ru/deepseek/chat/completions');
|
|||
|
|
|
|||
|
|
define('OPENAI_API_URL', 'https://api.proxyapi.ru/openai/v1/chat/completions');
|
|||
|
|
define('OPENAI_VISION_URL', 'https://api.proxyapi.ru/openai/v1/files');
|
|||
|
|
|
|||
|
|
error_reporting(E_ALL);
|
|||
|
|
ini_set('display_errors', 1);
|
|||
|
|
ini_set('log_errors', 1);
|
|||
|
|
ini_set('error_log', LOG_FILE);
|
|||
|
|
|
|||
|
|
require 'vendor/autoload.php';
|
|||
|
|
use GuzzleHttp\Client;
|
|||
|
|
|
|||
|
|
// 🔹 Функция логирования
|
|||
|
|
function logMessage($message) {
|
|||
|
|
file_put_contents(LOG_FILE, date('Y-m-d H:i:s') . " - " . $message . "\n", FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔹 Функция анализа текста через GPT-4-Turbo
|
|||
|
|
function analyzeTextWithGPT($text, $previousDocuments, $fileName) {
|
|||
|
|
logMessage("Отправка запроса в GPT-4-Turbo...");
|
|||
|
|
|
|||
|
|
if (!OPENAI_API_KEY) {
|
|||
|
|
logMessage("Ошибка: API-ключ не найден!");
|
|||
|
|
return ["error" => "API-ключ отсутствует"];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$task = "Проанализируй документ, следуя следующим пунктам:
|
|||
|
|
- Определи его тип (например, договор, претензия, подтверждение оплаты).
|
|||
|
|
- Проверь, соответствует ли название содержимому.
|
|||
|
|
- Выдай вердикт: 'Прошло модерацию' или 'Не прошло' (с указанием причин).
|
|||
|
|
- Проверка на ненормативную лексику и нецензурные изображения.";
|
|||
|
|
|
|||
|
|
$body = json_encode([
|
|||
|
|
// "model" => "deepseek-chat",
|
|||
|
|
"model" => "gpt-4o",
|
|||
|
|
"messages" => [
|
|||
|
|
["role" => "system", "content" => $task],
|
|||
|
|
["role" => "user", "content" => $text]
|
|||
|
|
],
|
|||
|
|
"max_completion_tokens" => 4000
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
logMessage("Запрос к GPT-4-Turbo: " . substr($body, 0, 1000));
|
|||
|
|
|
|||
|
|
$client = new Client();
|
|||
|
|
try {
|
|||
|
|
$response = $client->post(OPENAI_API_URL, [
|
|||
|
|
'headers' => [
|
|||
|
|
'Content-Type' => 'application/json',
|
|||
|
|
'Authorization' => 'Bearer ' . OPENAI_API_KEY
|
|||
|
|
],
|
|||
|
|
'body' => $body
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$response_data = json_decode($response->getBody(), true);
|
|||
|
|
logMessage("Ответ от GPT-4-Turbo: " . json_encode($response_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
|||
|
|
return $response_data;
|
|||
|
|
} catch (Exception $e) {
|
|||
|
|
logMessage("Ошибка запроса к GPT-4-Turbo: " . $e->getMessage());
|
|||
|
|
return ["error" => "Ошибка запроса к GPT-4-Turbo"];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔹 Функция конвертации PDF → JPG
|
|||
|
|
function convertPDFtoJPG($pdfFile) {
|
|||
|
|
logMessage("Конвертируем PDF в изображения: $pdfFile");
|
|||
|
|
|
|||
|
|
$outputDir = sys_get_temp_dir() . "/pdf_to_jpg_" . uniqid();
|
|||
|
|
mkdir($outputDir, 0777, true);
|
|||
|
|
|
|||
|
|
$cleanFileName = preg_replace('/[^\w.-]/u', '_', basename($pdfFile));
|
|||
|
|
$outputPath = $outputDir . "/" . $cleanFileName . "_page";
|
|||
|
|
|
|||
|
|
$command = "convert -density 300 " . escapeshellarg($pdfFile) . " -quality 90 " . escapeshellarg($outputPath) . ".jpg";
|
|||
|
|
shell_exec($command);
|
|||
|
|
|
|||
|
|
$jpgFiles = glob("$outputPath*.jpg");
|
|||
|
|
if (empty($jpgFiles)) {
|
|||
|
|
logMessage("Ошибка: не удалось конвертировать PDF в JPG.");
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("PDF успешно преобразован в " . count($jpgFiles) . " изображений.");
|
|||
|
|
return $jpgFiles;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔹 Функция отправки JPG в GPT-4-Vision (исправлена ошибка Content-Type)
|
|||
|
|
function analyzeImagesWithGPT($imageFiles) {
|
|||
|
|
logMessage("Отправляем изображения в GPT-4-Vision...");
|
|||
|
|
|
|||
|
|
if (!OPENAI_API_KEY) {
|
|||
|
|
logMessage("Ошибка: API-ключ не найден!");
|
|||
|
|
return ["error" => "API-ключ отсутствует"];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Собираем массив файлов для multipart/form-data
|
|||
|
|
$multipartData = [];
|
|||
|
|
foreach ($imageFiles as $index => $image) {
|
|||
|
|
$multipartData[] = [
|
|||
|
|
'name' => 'file', // API ожидает параметр `file`
|
|||
|
|
'contents' => fopen($image, 'r'),
|
|||
|
|
'filename' => basename($image),
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$client = new Client();
|
|||
|
|
try {
|
|||
|
|
$response = $client->post(OPENAI_VISION_URL, [
|
|||
|
|
'headers' => [
|
|||
|
|
'Authorization' => 'Bearer ' . OPENAI_API_KEY
|
|||
|
|
],
|
|||
|
|
'multipart' => $multipartData
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$body = json_decode($response->getBody(), true);
|
|||
|
|
logMessage("✅ Ответ от GPT-4-Vision: " . json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
|||
|
|
return $body;
|
|||
|
|
} catch (Exception $e) {
|
|||
|
|
logMessage("❌ Ошибка запроса к GPT-4-Vision: " . $e->getMessage());
|
|||
|
|
return ["error" => "Ошибка запроса к GPT-4-Vision"];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔹 Функция обработки PDF-файлов
|
|||
|
|
function processPDFFiles() {
|
|||
|
|
logMessage("Запуск обработки PDF-файлов...");
|
|||
|
|
|
|||
|
|
if (!shell_exec("which pdftotext")) {
|
|||
|
|
logMessage("Ошибка: pdftotext не установлен.");
|
|||
|
|
return json_encode(["error" => "pdftotext не найден"]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$files = glob(SCAN_DIR . '/*.pdf');
|
|||
|
|
if (empty($files)) {
|
|||
|
|
logMessage("Нет файлов для обработки.");
|
|||
|
|
return json_encode(["error" => "Нет файлов в директории " . SCAN_DIR]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$documentAnalysis = [];
|
|||
|
|
foreach ($files as $pdfFile) {
|
|||
|
|
logMessage("Обрабатываем PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
$text = shell_exec("pdftotext -layout " . escapeshellarg($pdfFile) . " -");
|
|||
|
|
if (empty(trim($text))) {
|
|||
|
|
logMessage("Файл $pdfFile содержит только изображения или пуст. Запускаем OCR...");
|
|||
|
|
$jpgFiles = convertPDFtoJPG($pdfFile);
|
|||
|
|
|
|||
|
|
if (!empty($jpgFiles)) {
|
|||
|
|
$imageAnalysis = analyzeImagesWithGPT($jpgFiles);
|
|||
|
|
logMessage("Результат анализа изображений: " . json_encode($imageAnalysis, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
|||
|
|
$text = json_encode($imageAnalysis, JSON_UNESCAPED_UNICODE);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!empty(trim($text))) {
|
|||
|
|
logMessage("Текст успешно извлечен, отправляем в GPT-4-Turbo.");
|
|||
|
|
$gptAnalysis = analyzeTextWithGPT($text, $documentAnalysis, basename($pdfFile));
|
|||
|
|
|
|||
|
|
if (!$gptAnalysis) {
|
|||
|
|
logMessage("Ошибка: GPT-4-Turbo не вернул ответ.");
|
|||
|
|
$documentAnalysis[] = ["file" => basename($pdfFile), "error" => "GPT-4-Turbo не ответил"];
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$documentAnalysis[] = ["file" => basename($pdfFile), "analysis" => $gptAnalysis];
|
|||
|
|
} else {
|
|||
|
|
logMessage("OCR и GPT-4-Vision не смогли обработать файл: $pdfFile");
|
|||
|
|
$documentAnalysis[] = ["file" => basename($pdfFile), "error" => "Невозможно обработать файл"];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Обработка всех файлов завершена.");
|
|||
|
|
return json_encode(["status" => "complete", "results" => $documentAnalysis], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Запуск обработки
|
|||
|
|
echo processPDFFiles();
|
|||
|
|
?>
|