29 сентября 2013 г.

Тестирование почтовой рассылки с помощью blat

Для автоматизации процесса верстки - тестирования почтовых рассылок под Windows я использую консольный почтовый сервер blat.
Загрузить blat можно с сайта проекта http://www.blat.net.

После распаковки в архиве. Перед тем как начать использовать утилиту, необходимо настроить параметры учетной записи smtp сервера.
Все указанные параметры будут сохранены в реестре.
#: blat.exe -install -server smtp.server.ru -port 25 -f your@mail.box -u your@mail.box -pw __password__
где smtp.server.ru адрес smtp сервера твоего любимого почтового сервиса. smtp.server.ru - учетная запись и  имя отправителя. __password__ пароль.

Как послать письмо с вложением
#: blat.exe -charset windows-1251 -to mail@yandex.ru -subject "Тема" -body "Тело письма" -attach "attach.txt"
Письмо по умолчанию будет отправлено в utf-8 (о чем следует помнить).  Ключ -charset windows-1251 у меня почему то не срабатывает.

Как отправить html файл (сверстанное письмо)
#: blat.exe body.html -s "Test mail" -i "Cybergavin Tester" -to mail@yandex.ru,mail@mail.ru,mail@gmail.com -html
Описание ключей:
-s => Тема письма ( тема письма по умолчанию "Contents of file: stdin.txt" )
-i => Имя отправителя (адрес отправителя указывается при настройке параметров smtp сервера)
-to => Адреса назначения через запятую
body.html => файл с версткой письма
-html => ключ для указания mime типа документа - HTML (Content-Type : text/html)

Если письмо содержит графику с сервера. То на время тестирования ее можно брать из расшаренной папки google drive. Google drive позволяет делать статические сайты из расшаренных папок (как и DropBox), поэтому в них можно сложить необходимую графику.

Полезные gem-ы ruby. chunky_png

Ruby удобный язык для создания подсобного инструментария. И основную ценность придает ему доступная система пакетов gem-ов. Одним из таких пакетов является gem chunky_png. [ <) https://github.com/wvanbergen/chunky_png ] chunky_png добавляет легкий api для работы с png. И в основном я его использую для генерации спрайтов - склейки png с небольшими трансформациями. Собственно, для этих целей он используется в compass.

Ставим gem
#: gem install chunky_png

Пример склейки png #1
require 'chunky_png'

files = ['btn1.png','btn2.png','btn3.png','btn4.png','close.png']
# Создадим png файл в который все поместим все картинки. 1-й параметр width, 2-й - height
png = ChunkyPNG::Image.new(70,70*4+32, ChunkyPNG::Color::TRANSPARENT)
yPos=0
files.each{|fname| # Перебираем файлы
    img = ChunkyPNG::Image.from_file(fname)
    png.compose!(img,0,yPos) # размещаем картинку в нужном месте
    yPos=yPos+img.dimension.height
}
png.save("btnSprites.png")

Пример склейки посложнее #2
require 'chunky_png'

# в спрайт нужно вставить оригинальное изображение, но иногда и отцентрировать в заданном периметре
files = [{
            :file => "attention.png" 
        },{
            :file => "check.png"
        },{
            :file => "coin.png"
        },{
            :file => "desctop.png",
            :width => 50, # зададим ширину и высоту квадрата в центр которого нужно вставить изображение
            :height => 50
        },{
            :file => "mobile.png",
            :width => 50,
            :height => 50
        },{
            :file => "question.png"
        },{
            :file => "letter.png",
            :width => 50,
            :height => 50
        }]

file_buf = []
max_width = 0
max_height = 0
css = "" # попутно сгенерируем css, раз мы и так знаем все координаты
css_x_pos = 0
css_y_pos = 0
save_file_name = "sprite" # название спрайта
css_class_name_prefix = ".home-room-free-fm-" # а в css будем вставлять классы с таким префиксом

files.each{|image|
    # вставляем оригинальное изображение
    if image[:width].nil? || image[:height].nil? 
        img = ChunkyPNG::Image.from_file(image[:file])
    # или  помещаем изображение в заданный периметр
    else
        img = ChunkyPNG::Image.new(image[:width],image[:height], ChunkyPNG::Color::TRANSPARENT)
        buf = ChunkyPNG::Image.from_file(image[:file])
        x_pos = ((image[:width] - buf.dimension.width)/2).round
        y_pos = ((image[:height] - buf.dimension.height)/2).round
        #puts "image[:width] `#{image[:width]}`, img.dimension.width `#{img.dimension.width}`, x_pos: `#{x_pos}`"
        img.compose!(buf,x_pos,y_pos)
    end
    
    if img.dimension.width > max_width
        max_width = img.dimension.width
    end
    max_height = max_height + img.dimension.height
    file_buf << img
}
png = ChunkyPNG::Image.new(max_width,max_height, ChunkyPNG::Color::TRANSPARENT)

# помещаем получившиеся фрагменты в спрайт
file_buf.each_with_index{|file,index|
    png.compose!(file,css_x_pos,css_y_pos)
    # а данные о координатах сохраняем в CSS:
    css = css +"#{css_class_name_prefix}#{files[index][:file]}{\n\tbackground:url(#{save_file_name}.png) #{css_x_pos > 0 ? (-css_x_pos).to_s+"px":"0"} #{css_y_pos > 0 ? (-css_y_pos).to_s+"px":"0"} no-repeat;\n\twidth:#{file.dimension.width}px;\n\theight:#{file.dimension.height}px;\n}\n"
    css_y_pos = css_y_pos+file.dimension.height
}
#css можно сохранить в отдельный файл

Рисование окружностей:
require 'chunky_png'

png = ChunkyPNG::Image.new(57, 57, ChunkyPNG::Color::TRANSPARENT)

png.circle(28, 28, 27, ChunkyPNG::Color(0x7b0f34FF), ChunkyPNG::Color::TRANSPARENT)
png.circle(28, 28, 25, ChunkyPNG::Color::TRANSPARENT,ChunkyPNG::Color(0x7b0f344D))
png.save("out3.png",:fast_rgba)
Гем поддерживает возможность рисования. Но по пиксельно, поэтому получившиеся окружности смотрятся хуже в отличие от прямых линий, чем если это делать в photoshop или gimp.

В место заключения. С помощью chunky_png можно с автоматизировать рутинные действия с графикой. Не дергать дизайнера при каждом изменении в наборе фрагментов.