Понадобилось мне, чтобы торрент клиент оповещал меня в QIP о закачке очередной порции добра.
Ринулся я искать подходящую утилиту с интерфейсом командной строки для отправки XMPP сообщений… и ничего не нашел — кругом клиенты, не заточенные для нужд автоматизации. Отсутствие очевидных кандидатов подвигло меня к написанию собственной утилиты.
Для того, чтобы быстро сваять что-то для собственного потребления я использую ruby.
Весь код помещается в 12 строк, хотя конечно можно ужать и в одну.
require 'rubygems'
require 'xmpp4r/client'
include Jabber
server, login, password = "qip.ru", "my_login", "my_password"
to, subject, body = "someone@qip.ru", "XMPP4R test", "Hi, this is my first try from XMPP4R!!!"
Jabber::debug = true
jid=JID::new "#{login}@#{server}"
cl = Client::new(jid)
cl.connect
cl.auth password
m = Message::new(to, body).set_type(:normal).set_id('1').set_subject(subject)
cl.send m
После того, как я убедился что скрипт работает, решил реализовать разбор праметров командной строки и возможность передавать скрипту постоянные параметры ( такие как [сервер, логин, пароль] ) через конфигурационный файл, чтобы не перегружать командную строку. Что из этого получилось можно посмотреть тут. Или по прямым ссылкам: xmpp_sender.rb, xmpp_sender.yml, setup.exe
Запущенная без параметров эта утилита прочтет параметры из конфига и пошлет тестовое собщение на специальный тестовый qip-логин. Чтобы увидеть справку используйте параметр -h. Чтобы воспользоваться этой утилитой для отсылки уведомлений rtorrent-ом, читайте тут
После того как утилита была написана и протестирована, я задумался о том, что неплохо ее оформить в виде exe файла, который можно было бы просто поместить в папку на компьютере и настроить вызов этого exe из rtorrent. А то получается довольно неудобно — надо ставить ruby, указывать в rtorrent вызов ruby c путем к скрипту, с путем к конфигу… Да и просто стало интересно разобраться с темой упаковки ruby приложения в exe файл. Помню, еще пару лет назад пробовал rubyscript2exe и ocra, но почему-то тогда они меня не впечатлили — не помню уже подробностей, но что-то было кривовато. В этот раз решил попробовать снова.
Согласно ruby-toolbox Есть три пакета для упаковки ruby в исполняемый файл: rubyscript (уже не развивается), crate, ocra. Я сразу начал с ocra, как с самого популярного.
Ocra фактически создает самораспаковывающийся архив, в который упаковывает интерпретатор ruby, геммы и собственно ruby-скрипты приложения. При запуске exe архив распаковывается во временный каталог, запускает в нем ruby со скриптом и передает ему параметры своей командной строки.
Скомпилировался exe без сложностей: ocra xmpp_sender.rb
Я запустил его и получил на экран сообщение от встроенного файрвола Windows с запросом о том, заблокировать или разблокировать ruby — выбрал разблокировать. Тем не менее этот запрос появлялся каждый запуск моего exe.Неудивительно, т.к. exe распаковывался всякий раз в разную папку во временном каталоге и поэтому файрвол считал его новой программой.
На форуме рубистов мне посоветовали воспользоваться Inno Setup — программой для создания инсталляторов Windows программ.Признаться, я сразу подумал о том, что получившийся инсталлятор будет запускать инсталлятор руби, как это бывает, когда ставишь какую-нибудь игру — сначала запускается отдельный инсталлятор directx, потом origin, потом еще чего-нибудь и только потом игра, но я ошибся.
Ocra так удачно использует Inno Setup, что интерпретатор ruby устанавливается вместе с exe и rb-скриптами одновременно и незаметно для пользователя. Так, как интерпретатор устанавливается однократно и в определенный каталог, то и разблокировать его файрволу нужно будет всего лишь раз.
Перед запуском ocra нужно запустить Inno Setup и создать проект инсталлятора в папке с приложением ruby.
При запуске надо выбрать создание нового скрипта при помощи Мастера. Далее все тривиально. На стадии выбора файлов естественно нужно выбрать «The application doesn't have a main executable file», затем надо выбрать файлы, которые должен установить инсталлятор. Не нужно выбирать rb-файлы, т.к. они будут выбраны ocra автоматически. В моем проекте я выбрал файлы readme, license, yml-конфиг.
После того как создан скрипт файл инсталлатора, он будет показан с вопросом надо ли его компилировать. Следует кликнуть Нет.
Запускаю опять ocra:ocra --chdir-first --no-lzma --innosetup xmpp_sender.iss --icon doc/images/logo_icon.ico xmpp_sender.rb
Ocra запустит скрипт и в процессе его работы будет наблюдать какие приложению требуются геммы и dll-и, и после завершения пропишет их все в проект инсталлятора и запустит Inno Setup, который и соберет setup.exe.C:InstantRailsruby_appsxmpp_sender>ocra --chdir-first --no-lzma --innosetup xmpp_sender.iss --icon doc/images/logo_icon.ico xmpp_sender.rb
=== Loading script to check dependencies
working directory: ./
@server: qip.ru
@login: xmmp-sender
@password: xmmp-rednes
@to: xmmp-sender-test
@subject: first run
@body: Hey Zloy, I tried xmpp sender too. Best wishes!
=== Detected gem xmpp4r-0.5 (loaded, files)
=== 10 files, 39247 bytes
=== Building xmpp_sender.exe
=== Adding user-supplied source files
=== Adding ruby executable ruby.exe
=== Adding detected DLL C:/InstantRails/ruby/bin/libeay32-0.9.8-msvcrt.dll
=== Adding detected DLL C:/InstantRails/ruby/bin/ssleay32-0.9.8-msvcrt.dll
=== Adding detected DLL C:/InstantRails/ruby/bin/ZLIB1.dll
=== Adding library files
=== Running InnoSetup compiler ISCC
C:InstantRailsruby_appsxmpp_sender>
Inno Setup создаст подпапку Output куда и поместит готовый Setup.exe. Эту папку можно поменять в скрипте на OutputDir=. чтобы Setup.exe был в корне папки установки.
Размер инсталлятора оказался ~1,5 Мб, что по нынешним меркам совсем мало. Размер каталога, установленного инсталлятором приложения, составляет ~5 Мб, что конечно многовато для подобной утилиты, но меня устраивает.
В итоге:
легко распространять — один файл setup.exe весом в 1.5 Мб
просто устанавливать и сносить
можно легко изменить для собственых нужд, т.к. исходники прилагаются
В общем, рекомендую ruby и ocra!