klink0v (klink0v) wrote,
klink0v
klink0v

Колхозим JPG→PDF конвертер

Тут задали мне юристы задачку. Они сканируют какие-то документы в JPG (родная софтина от сканера по-другому не умеет), а на выходе очень хотят получить PDF. Да не абы какой, а многостраничный. Чтобы N отсканированных страниц поместились бы в итоге в одном файле.

Естественно, покупать для этих целей полновесный Adobe-овский акробатический пакет жаба задушит. Есть прекрасные альтернативы типа того же самого ImageMagick, да вот только незадача: работают они из командной строки. Юристы навряд ли разберутся, хоть они у нас достаточно продвинутые и в делах компьютерных в том числе.

Стал чесать репу. Думаю: коль скоро у меня всё равно есть линуксовая файлопомойка, почему бы не заставить её заодно и картинки конвертировать? Сказано — сделано. На самбовой расшарке организовал отдельную папочку. Установил ImageMagick. На папочку натравил простенький шелл-скриптик такого вот содержания.

#!/bin/bash

DIR="/usr/share/samba/pdf"

umask 011
FILE="$DIR/"`/bin/date +%y%m%d%H%M`".pdf"

/usr/bin/find $DIR -iregex ".+\.jpe?g" -print0 | sort -z | \
 xargs -r -0 /bin/bash -c \
  'sudo -u nobody /usr/bin/convert "$0" "$@"'" $FILE "'&& rm "$0" "$@"'

Здесь find ищет внутри папки все файлы с расширениями "jpg" и "jpeg", найденное сортируется в алфавитном порядке при помощи sort, затем xargs-ом скармливается ImageMagick-у ("convert"). Результат складывается в файл, который именуется банально как текущая дата и время плюс расширение ".pdf".

Дальше возникает вопрос, по какому событию запускать этот скриптик. По крону? Можно, но как-то некрасиво. Вспоминаем, что в пингвиньем ядре существует достаточно эффективный механизм inotify. Надо только подобрать какую-нибудь утилитку, чтобы его попользовать. Первое что пришло в голову — lsyncd.

Вообще-то последний изначально задумывался как инструмент для синхронизации. Но с другой стороны, какая нам разница, коли он умеет "вешать" на папку notification-ы и запускать произвольный бинарник (или скрипт) по факту возникновения изменений в этой папке.

Начиная со 2-й версии конфиг для lsyncd пишется на Lua. Но в стабильном дебиане по умолчанию идет 1-ая версия, а гоняться за "свежаком" мне было, как обычно, лень. Поэтому я не стал выё  выпендриваться и написал свои конфигушки на старом добром XML. Получилось что-то типа того.

<lsyncd version="1">

<settings>
    <scarce/>
    <logfile      filename="/var/log/lsyncd/lsyncd.log"/>
    <binary       filename="/usr/local/bin/pdf"/>
    <pidfile      filename="/var/run/lsyncd/lsyncd.pid"/>
    <delay value="30"/>
</settings>

<directory>
    <source path="
/usr/share/samba/pdf"/>
    <target path="/dev/null"/>
</directory>

</lsyncd>

Обязательно задать какой-нибудь "source path" (папка, за которой следим) и "target path" (нужен для нормальной работы lsyncd). Остальные параметры не обязательны. Ключ "delay" говорит о том, сколько секунд надо подождать прежде чем начинать что-то делать. Действительно, мы заранее не знаем сколько файлов захочет положить в расшаренную папку пользователь. Но на гигабитной-то сети тридцати секунд должно по идее хватить с большим запасом на то, чтобы туда успело скопироваться всё что нужно. В "binary" указал путь до "конвертирующего" скрипта (см. выше).

Всё. Запускаем демон lsyncd и наслаждаемся эффектом. С точки зрения пользователя это выглядит следующим образом. Он копирует в заранее заданную расшаренную папку пачку JPG-файлов, ждет чуть меньше минуты, после чего забирает оттуда же готовый PDF. Просто и привычно.

Да, согласен, это колхозное решение. Более расово правильно было бы организовать какой-нибудь модный Web-интерфейс с AJAX-ом. Зато оно работает и может быть изготовлено "на коленке" менее чем за полдня любым знакомым с *nix системным администратором, даже не имеющим навыков программирования.



Ретранслировано из Я.ру
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 5 comments