Чтение файлов в форматах fb2,epub, pdf, txt. Обработка парсит текст используя механизм регулярных выражений.




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

22 Comments

  1. Franco

    …Для формата fb2 поддерживается ночной режим

    А что это?

    Reply
  2. XOCTEP

    (1) Это черный фон и белый текст, а обычный режим наоборот

    Reply
  3. gaglo

    А зачем «fb2 парсятся с использованием регулярных выражений», а не используется какая-либо из техник чтения XML?

    Reply
  4. Ekovichev

    Ради скорости. Перебирать все узлы xml для нахождения определённых конструкций(например вшитых картинок) дольше, чем используя рег. выражения. Чтение xml используется только для определения кодировки текста в fb2.

    Reply
  5. DmitryKishkin

    Нормальненько так работает…

    Reply
  6. Severus

    Автору за реализацию идеи, однозначно плюс!)

    Надеюсь на дальнейшее развитие идеи и добавление механизмов разбиения книги на страницы, реализацию закладок, прогресс бара, изменения/добавления шрифтов, смена яркости фона(или самого фона) 🙂

    Reply
  7. Ekovichev

    Да я увидел обработку для чтения pdf файлов и решил развить идею, ради интереса сделал.Если будет свободное время все добавлю:)

    Reply
  8. Totoro

    Норм. Работает шустро.

    1. При выборе файла добавить еще один общий фильтр для всех форматов книг (все равно потом расширение анализируешь).

    2. Для формата fb2 лучше сделать не структуру жанров, а соответствие и в случае, если жанр в соответствии не найден, то возвращать как есть (чтобы по ошибке не выпадала в случае самопридуманных жанров).

    Reply
  9. Alever

    Неплохо было бы добавить сюда варианты конвертации. Со многих форматов в fb2 — то есть можно было бы использовать обработку не только в качестве читалки, но и в качестве конвертера для дальнейшего сохранения файлов. Плюс я думаю неплохой идей для разработчика может послужить написание этой обработки для тонкого клиента? Ну и расширения форматов =) А так вообще классно.

    Reply
  10. Ekovichev

    На выходных займусь, сделаю на УФ, добавлю разбиение по страницам, закладки и список ранее открытых книг. Исправлю замечания и ускорю чтение, насчет конвертера подумаю:)

    Reply
  11. mzelensky

    Хорошая обрабтка. Правда я ее немного не по назначению юзаю. Но нравится 🙂

    Автору +

    Reply
  12. Ekovichev

    (11) mzelensky, По какому, если не секрет?)

    Reply
  13. mr.Kot

    Разработка интересная, слабо представляю ситуации, когда данные форматы реально нужно открывать через предприятие, но тем не менее — плюс!

    Reply
  14. Ekovichev

    (13) mr.Kot, я часто подрубаюсь к пользователям, они читают, вместо того, чтобы работать. Можно читать непосредственно в рабочей программе 🙂 Это просто развлечение, конечно практического применения мало.

    Reply
  15. gaglo

    (4) Так в читалке применяется самый общий механизм регулярных выражений на текстовую строку?

    Я потому интересуюсь, что для «перебирать все узлы xml для нахождения определённых конструкций» вроде бы специально придуман XPath-механизм; а еще, чтоб отобразить FB2, да и EPUB, все равно надо весь файл считать. Откуда ж скорость берется?

    Reply
  16. Ekovichev

    (15) gaglo, Да верно, применяется механизм регулярных выражений. Так совпало, что я как раз погрузился в пучину RegExp:) и решил применить их на практике. Регулярные выражения при работе со строкой являются очень шустрыми, правда в них черт ногу сломит. А вот применять DOM объекты для того, чтобы распарсить fb2 и epub я не стал, изначально подумал, что слишком много DOM жрет ресурсов. Читалка на управляемых формах находится на модерации, если будет время я попробую сделать еще версию и распарсить через xPath.

    Reply
  17. DAnry

    Превращаем 1С в супер-пупер развлекательный медиацентр. Мне кажется это уже черезчур…

    Reply
  18. Ekovichev

    (17) DAnry, Дело не в развлечениях. Мне надо было разобраться с регулярками. Для того, чтобы совместить полезное с приятным, написал эту штуку. Может кто-то парсит HTML, тому обработка может помочь и т.д.

    Reply
  19. makas

    Какая полезная вещица, возьму в свою копилочку идей!

    Reply
  20. mzelensky

    (12) Ekovichev, Внешние документы парсю 🙂

    Reply
  21. Stim213

    Хорошая идея. Только добавьте еще «мод» для тех, кто не хочет палиться — чтобы любой заглянувший в монитор программиста был уверен, что он занят чем-то в 1С, а не читает книгу)

    Reply
  22. POLGA

    Однако на управляемых формах при чтении .fb2 выдает ошибку (при отсутствии в структуре жанра russian_contemporary), пришлось заменить сточку :

    Возврат ?(СтруктураЖанр.Свойство(Жанр), СтруктураЖанр[Жанр], Жанр); — так ошибку не выдает.

    .epub — один не прочла (возможно что-то с файлом — выдала пусто без сообщений),в другом — не показывает картинки.

    .pdf один прочитала на втором вылетела из 1С совсем.

    Возможно все-таки есть ограничения…

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *