Буду на DevConf, Москва, 17-18 мая

Опубликовано 05.05.2010

Нынче у меня весна конференций – еду на 17-18 мая на DevConf::Ruby. Буду участвовать по полной – читать доклад и проводить мастер-класс.

Доклад: Разработка приложений под Facebook на Ruby on Rails

Я когда-то уже читал этот доклад в Омске на RuPyRu. С тех пор много чего случилось: я создал свой собственный полноценный движок для создания текстовых RPG-игр, продал его довольно большому количеству клиентов, перешел с разработки FBML-приложений на IFRAME-приложения, раскурил концепцию Facebook for Websites и наткнулся на многие подводные камни разработки приложений для социальных сетей. Всем этим опытом я и хочу поделиться.

Доклад может быть полезен тем разработчикам, кто планирует разрабатывать приложения под Facebook или интегрировать с ним существующее приложение. При нынешней аудитории в 400 миллионов пользователей платформа приложений Facebook сама по себе уже является очень привлекательным рынком разработки. Очень многие западные проекты уже в той или иной степени интегрированы с этой социальной сетью и еще больше будет интегрировано в ближайшие год-два. Если вы занимаетесь разработкой на западный рынок – вам сам Бог велел приехать и послушать про грабли, на которые вам 100% предстоит наступить при интеграции вашего приложения с Facebook.

Плюс в кулуарах можно будет задавать вопросы о том, как можно продавать Rails-приложения за деньги. Не делать на заказ, а продавать как shareware :) Но это так, по секрету, эксклюзивно для читателей блога, в официальной программе этого нет.

Мастер-класс: Оптимизируем Ruby on Rails приложение под высокие нагрузки

В ходе работы над Rails-проектами с различной посещаемостью – до нескольких сот тысяч пользователей в сутки – у нас сформировался некий набор техник, которые помогают обеспечить работоспособность приложений под высокой нагрузкой. Собственно, техники все давно известные – кэширование, оптимизация запросов, распределение нагрузки и т.д. В ходе мастер-класса я расскажу о том, как эти техники оптимально применить, какой софт использовать, а так же об ошибках, которые может допустить разработчик при оптимизации приложения. В общем-то я не планирую срывать покровы и раскрывать тщательно охраняемые тайны. Просто расскажу что и как мы делали и какие бонусы и геморрои получили в результате.

Мастер-класс будет полезен в первую очередь тем разработчикам, кто разрабатывает или планирует разрабатывать приложения, которые будут обслуживать десятки и сотни тысяч человек в сутки. Если б мне год-два назад предложили посетить подобный мастер-класс и сэкономить себе нервы в будущем – я бы и минуты не стал раздумывать.

Помимо меня на конференции будет еще небезызвестный Yehuda Katz – один из ведущих разработчиков Rails 3. Будет интересно посмотреть, у кого из нас борода длиннее :) Также доклады будут читать Евгений Хлызов, Дмитрий Галинский, Иван Самсонов и многие другие

В общем, приглашаю и вас принять участие. Я уверен, вы узнаете для себя много интересного.

Консоль класса Люкс

Опубликовано 05.04.2010

При работе с Rails-приложениями довольно много времени я провожу в консоли. Стандартный функционал, предоставляемый IRB по умолчанию, не сказать чтобы шибко богат. Вчера нашлось у меня немного свободного времени, чтобы улучшить свое скромное житие-бытие.

Настройки IRB-консоли задаются в файле .irbrc в домашней директории пользователя. Это по сути обычный ruby-файл, в нем можно подключать различные gem-ы, добавлять методы и т.д.

Вот несколько маленьких трюков для улучшения стандартной консоли, которые мне удалось раскопать (итоговый файл конфигурации см. в конце статьи):

  • wirble – добавляет посветку в стандартный вывод IRB и добавляет поддержку истории выполнения команд
  • awesome_print – позволяет выводить объекты на экран в удобном формате и с подсветкой. Использование в консоли:
    ap this_is_my_object
  • looksee – позволяет посмотреть список методов объекта, разбитый по классам/модулям, из которых эти методы происходят. Очень удобно при исследовании внутренностей классов и модулей фреймворка при отладке или разработке плагинов. Использование в консоли:
    lp this_is_my_object
  • Вывод лога SQL-запросов в консоль – при работе с моделями ActiveRecord все запросы к БД будут выводиться прямо на экран:
    show_log # включаем логи
    hide_log # выключаем логи
  • Замер скорости выполнения кода:
    time { ... }      # Код выполнится 1 раз
    time(100) { ... } # Код выполнится 100 раз
  • Выполнение SQL-запроса:
    sql "SELECT count(*) FROM users"

Надо сказать, работать в консоли стало в разы удобнее.

Итоговый файл .irbrc можно взять здесь

А вы используете какие-нибудь дополнения для IRB-консоли?

DoS-уязвимость в Ruby

Опубликовано 10.06.2009

В ruby найдена уязвимость к DoS-атаке. Злоумышленник может вызвать нарушение работы интерпретатора, передав очень большое значение в функцию, использующую BigDecimal. Уязвимости подвержены следующие версии ruby:

  • Ruby 1.8.6-p368 и более ранние
  • Ruby 1.8.7-p160 и более ранние
  • Ruby Enterprise Edition 20090520 и более ранние

Код, с помощью которого можно выявить наличие проблемы (можно выполнить, например, в irb-консоли):

require 'bigdecimal'
BigDecimal("9E69999999").to_s("F")

Программисты из Phusion буквально только что выпустили исправленную версию Ruby Enterprise Edition. Советую всем обновиться до новой версии.

Как выбрать хостинг для Rails

Опубликовано 27.04.2009

После установки на сайте чата ко мне стали периодически стучаться люди и задавать разные вопросы. Особенно часто я получаю вопрос о том, где лучше всего хостить Rails-приложения. Вопрос, прямо скажем, очень похож на “какую машину лучше всего купить”. Ответ на него очень сильно зависит от того, что вы собираетесь с этой машиной делать – дрифтовать по улицам, лазать по горам, возить холодильники или катать инвестиционных банкиров. Выбор хостингы в этом отношении нисколечки не отличается и тоже очень сильно зависит от того, какие приложения вы собираетесь хостить. Давайте рассмотрим наиболее важные параметры, которые нужно учесть при выборе хостинга.

Расположение

Перед тем, как выбирать хостинг-провайдера, вы должны четко осознавать, где живут ваши основные посетители. Если это россияне или жители СНГ – нет смысла покупать хостинг в США. Равно как и наоборот. Несмотря на то, что скорость каналов растет, разница будет сильно чувствоваться, особенно если в вашем проекте много графики, видео или другого тяжелого контента. Поэтому хостера лучше выбирать среди тех, чьи сервера располагаются в стране, в которой живут ваши посетители.

Тип хостинга

Платформа Rails гораздо более требовательна в плане хостинга, чем, скажем, PHP, поэтому далеко не каждый провайдер поддерживает эту платформу. А среди тех провайдеров, которые заявляют о поддержке, далеко не все предлагают приемлимый вариант развертывания. Поэтому shared-хостинг – не лучший вариант для размещения рельсового приложения. Если вы действительно очень сильно ограничены в средствах (хотя я уверен, что выделить лишние $10 на нормальный хостинг – надуманная проблема), то при выборе shared-хостинга с поддержкой Rails обратите внимание на то, чтобы хостинг-провайдер предоставлял для развертывания модуль Passenger, а не FastCGI или CGI. Два последних варианта – большой геморрой. Если не уверены в том, каким образом вам предстоит поднимать приложения на данном провайдере – обязательно проконсультируйтесь со службой поддержки.

Если все же нашлась лишняя десятка, то уже можно покупать VPS – виртуальный сервер с позможностью настройки. Этот вариант хорош тем, что вы не ограничены тем набором программного обеспечения, которое хостер счел необходимым, и вольны устанавливать необходимое ПО по своему вкусу. VPS приемлем для небольших и средних проектов со сравнительно небольшой нагрузкой и является идеальным вариантом для старта нового проекта.

Если же проект достаточно крупный или ресурсоемкий, то вам потребуется выделенный сервер (dedicaded) или даже cloud-платформа вроде Amazon EC2. Хотя, если вы работаете с таким проектом, вы наверняка уже все знаете сами :)

Далее речь пойдет преимущественно о VPS и Dedicaded.

Специализация

При выборе хостинга очень важно, чтобы у техподдержки хостера уже был опыт работы с проектами на Rails, в противном случае вам придется решать все проблемы самостоятельно и, возможно, даже учить этому специалистов хостера. Чтобы такого не было, выбирайте хостеров, которые упомянаются в статьях о Rails, в сообществах, форумах, а так же тех хостеров, которые специализированно занимаются поддержкой Rails-проектов. Очень желательно, чтобы хостер предоставлял инструкции по настройке Rails и сопутствующего ПО на своих серверах.

Объем памяти

Среднее Rails-приложение занимает в оперативной памяти порядка 100 мегабайт на один процесс, на меньшее вряд ли стоит рассчитывать (особенно если вы используете RMagic, но тут готовьтесь к худшему). Поэтому минимальный объем оперативной памяти, который можно считать приемлимым – 256 мегабайт. С ростом посещаемости вам придется поддерживать несколько процессов одновременно, поэтому оперативной памяти потребуется больше.

Объем дискового пространства

Необходимый объем дискового пространства зависит от того, будет ли в вашем проекте возможность загрузки изображений, видео и других файлов. Если нет – объем диска для вас практически не важен, само приложение занимает очень мало места. Если загрузка файлов имеет место, то объем диска нужно рассчитывать из общего количества файлов и их среднего объема. Например, для изображений с фотоаппарата можно посчитать так: до 5 мегабайт на изображение плюс еще 1 мегабайт на уменьшенные копии. Итого на каждые 1000 картинок – порядка 6 гигабайт.

Бэкап

Для VPS и dedicaded-хостинга весьма актуально то, как организовано резервное копирование данных. Если хостер берет эти заботы на себя и это включено в план – очень хорошо. Некоторые хостеры предлагают резервное копирование в качестве дополнительной услуги за небольшую плату. Если же резервного копирования не предусмотрено вовсе – можно относительно недорого организовать резервное копирование на Amazon S3. Так или иначе, этот момент обязательно нужно учитывать.

Масштабируемость

Хорошим проектам свойственно вырастать. Заранее покупать сверхмощный сервер не стоит, однако о возможности роста стоит задуматься заранее. При выборе хостера обратите постарайтесь узнать, насколько легко будет, например, увеличить объем оперативной памяти для проекта или объем диска. Если вы арендуете выделенный сервер, узнайте, насколько быстро хостер сможет поставить новый сервер для переезда.

Для крупных проектов также важно, чтобы у хостера была возможность аренды серверов с различной конфигурацией, заточенной под решение конкретных задач. Например, отдельных серверов для баз данных, хранения и раздачи файлов, обработки видео и других специализированных задач.

Поддержка

Рано или поздно какие-то вопросы или проблемы с хостингом все равно возникнут, поэтому лучше выбрать хостера, который заранее дает ответы на наиболее часто возникающие вопросы. Установка и настройка ПО, обновление, бэкапы, масштабирование – чем больше ответов известно заранее, тем меньше нервов вы потратите в трудных ситуациях. Для решения особо сложных вопросов вам придется обращаться в службу поддержки, поэтому лучше заранее удостовериться, что с ней можно иметь дело. Сделать это проще всего попросив поделиться опытом тех, кто уже пользуется услугами выбранной вами компании.

Цена

Стоимость хостинга не должна являться оределяющим фактором. Если стоимость хостинга для вас важнее, чем надежность – возможно, вы выбрали не ту платформу. Подумайте, может еще не поздно перейти на PHP, его можно хостить практически бесплатно :)

Если вы все же уверены, что Rails – это ваш выбор, будьте готовы к тому, что стоимость нормального хостинга начинается где-то от $20. Это стоимость VPS с 256МБ оперативной памяти и 10ГБ диска. Найти дешевле довольно сложно, но можно.

Надеюсь, я смог ответить хотя бы на самые базовые вопросы, которые могут возникнуть при выборе хостинга для Rails-приложений. Если что-то упустил – обязательно сообщите мне об этом в комментариях


Внимание! Это последняя заметка, которую вы можете прочитать в старой RSS-ленте. Если вам нравится читать Записки из тех.отдела через RSS – подпишитесь на новую ленту по адресу http://feeds2.feedburner.com/railorz

Пользовательский контент

Опубликовано 07.03.2009

Еще со времен запуска первой версии Записок я ношу в себе идею разработки собственного блогодвижка. Задача, казалось бы, не ахти какая сложная и очень многие ее успешно решают, движков понаписано великое множество на всех языках. Собственно, поэтому идея и пролежала в моей голове без дела почти 4 года. И вот буквально после новогодних праздников я наконец нашел достойный повод взяться за нее – блоги практически не представлены на Facebook.

Существует всего несколько приложений под Facebook, относящихся в той или иной степени к блоггингу. Стандартные записки (Notes) убивают всякий коммерческий интерес к разработке альтернатив. И тем не менее, я взялся такую альтернативу создать, в первую очередь ради эксперимента. Получилась вот такая штука: Blog Box (демонстрационный блог)

По ходу работы над приложением выявилось множество нюансов, которые встречаются от проекта к проекту. Одним из первых вопросов, с которыми я столкнулся – как работать с пользовательским контентом.

Разметка

Практически каждый человек хочет как-то разнообразить свои посты, добавить в них ссылки, выделить текст жирным или курсивом, вставить список или табличку. Надо понимать, что большинство пользователей не знают и знать не хотят что такое HTML. В блогоплатформах для пользователей обычно ставится WYSIWYG-редактор типа TinyMCE, FCKEditor, Xinha или любой другой. Однако в Facebook такой вариант не пройдет – платформа очень жестко контролирует JavaScript, используемый приложением, и практически сводит на нет возможность использования готовых библиотек.

Для ручной разметки текста и избавления от необходимости в визуальном редакторе можно использовать упрощенные системы разметки, которые часто применяются в wiki-системах. Для Ruby есть два реализованных формата разметки – Textile (с помощью RedCloth) и Markdown (с помощью BlueCloth). Textile более гибок в плане стилевой разметки, Markdown проще для освоения. Я решил остановиться на Textile.

Обработку текста я вынес в отдельный хелпер, единый как для постов, так и для комментариев:

def format_content(content)
  textilize(content.to_s)
end

Метод textilize – стандартный рельсовый, становится доступен после установки RedCloth. Для обработки постов и комментариев я создал отдельные хелперы, передающие соответствующий контент для форматирования:

def post_content(post)
  format_content(post.text)
end

def post_excerpt(post)
  post.excerpt.blank? ? post_content(post) : format_content(post.excerpt)
end

def comment_content(comment)
  format_content(comment.text)
end

Далее вызываем нужные нам хелперы хоть на странице просмотра поста, хоть при выводе списка постов.

Очистка HTML

Если честно, я ожидал, что мое приложение сразу кто-нибудь попробует использовать в гнусных целях, похакать, засунуть XSS или какой-нибудь мерзкий JavaScript. Однако я не ожидал, что это случится в первый же день жизни приложения. Хорошо, что я озаботился где возможно прикрыть вывод пользовательских данных с помощью хелпера h():

<%=h @post.title %>

Однако текст поста, который форматируется с помощью Textile, так не обезопасишь. Поэтому следующее что пришлось делать – это очистку текста постов от потенциально опасных тэгов и атрибутов. Для решения этой задачи существует несколько различных вариантов. В рельсах есть встроенный хелпер для очистки от ненужных тэгов – sanitize. Есть сторонние решения, такие как xss_terminate, Dryopteris или sanitize, использующие возможности более быстрых библиотек для работы с HTMLHpricot и Nokigiri.

Я решил использовать в своем проекте плагин Sanitize – он для меня оказался более удобен в конфигурировании. Для интеграции с моделями я написал небольшой модуль, в котором немного поменял стандартные схемы очистки тэгов и атрибутов, а также добавил метод sanitize_attributes для быстрого привязывания очистки атрибутов. Весь входящий HTML разбирается средствами Hpricot, вычищаются ненужные тэги и атрибуты, добавляются нужные атрибуты (например, rel=nofollow для ссылок из комментариев) и обработанный код сохраняется в БД.

Специальные тэги

Мое знакомство с блоггингом, как и у многих, началось с LiveJournal. Система во многом неудобная, но в ней есть одна изюминка, которая мне очень нравилась – специальные тэги. Например, если я вставлю в текст поста тэг <lj user="my_friend">, то в тексте поста будет показана красиво оформленная ссылочка на журнал моего друга со всплывающей по наведению мышки информацией. Фишка очень интересная и я обязательно хотел использовать ее в своем блогодвижке.

Что самое смешное, я был даже вынужден ее использовать, когда дело дошло до вставки видео. В Facebook есть суровое ограничение на то, какие тэги можно использовать на страницах, а какие – нет. Это ограничение касается и тэга <object>, который по факту запрещен. Вместо него для вставки Flash используется тэг <fb:swf>, однако он сильно ограничен в плане конфигурирования. Видео-хостинги же для вставки видео дают только код на основе тэга <object>, без вариантов. Я задумался.

Решение нашлось довольно быстро – выводить обычный код вставки видео внутри тэга <iframe>, на который ограничение не накладывается. Однако опять же, код для iframe нужно каким-то образом сформировать, да и сам iframe нужно как-то вставить. Для формирования кода я решил использовать плагин acts_as_unvlogable, позволяющий из URL страницы с видео сформировать код. Вопрос со вставкой iframe встал на первый план.

На помощь пришла библиотека Radius, ключевая фишка Radiant CMS. С ее помощью можно создавать свои тэги, которые затем парсятся и обрабатываются ruby-кодом. Для размещения видео пользователю необходимо сформировать и вставить в текст поста вот такой код:

<bb:video url="http://www.youtube.com/watch?v=v9Lj0lF9Lao"></bb:video>

Обработка radius-кода вынесена в отдельный модуль, упрощающий добавление новых тэгов и их использование. Метод класса define_tag объявляет новый тэг, создает из блока метод экземпляра, который вызывается при обработке тэга, а так же добавляет тэг в общий список спец-тэгов, который можно затем использовать для расширения схемы очистки HTML, используемой sanitizer’ом:

  • Blogbox::RadiusContext.tags_with_namespace – все спецтэги
  • Blogbox::RadiusContext.tag_attributes – все разрешенные атрибуты

Для того, чтобы подключить спец-тэги стразу везде, меняем хелпер форматирования контента и хелперы вывода постов и комментариев:

def format_content(content, assigns = {}, &block)
  textilized_content = textilize(content.to_s)

  @@radius_context ||= Blogbox::RadiusContext.new(&block)
  @@radius_context.set_current_context(self, 
    assigns.merge(
      :view       => self,
      :controller => controller
    )
  )

  Radius::Parser.new(@@radius_context,
    :tag_prefix => Blogbox::RadiusContext::NAMESPACE
  ).parse(textilized_content)
end

def post_content(post)
  format_content(post.text, :post => post)
end

def post_excerpt(post)
  return post_content(post) if post.excerpt.blank? 

  format_content(post.excerpt, :post => post)
end

def comment_content(comment)
  format_content(comment.text, :post => post, :comment => comment)
end

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

Резюме

Пользовательский контент – далеко не банальная вещь. Здесь есть и подводные камни, и простор для творчества, и необходимость в разумном обстоятельном подходе. Если вы работаете с пользовательским контентом – заранее обдумайте, какие возможности вы хотите дать пользователю и какие точно не хотите давать. Исходя из специфики задачи и среды можно использовать те инструменты, которые уже разработаны ruby-сообществом, и сделать свой проект по истине уникальным.

Сервис доставки сообщений (концепт)

Опубликовано 13.12.2008

При разработке портала передо мной возникла задача создания единого сервиса доставки сообщений от различных сервисов до пользователя. Если вы работаете над проектом, состоящим из одного сервиса - вам будет вполне достаточно средств ActionMailer. Однако если ваш проект состоит из нескольких сервисов - возникают сложности.

Задача

В моем случае задачу можно сформулировать следующим образом:

  1. Персональные данные пользователя (email, имя, все персональные настройки) хранятся в сервисе Паспорт
  2. Отправка сообщений пользователю должна осуществляться всеми сервисами портала, коих на данный момент 4
  3. Сервисы могут отправлять следующие типы сообщений:
    • Разовые сообщения о системных событиях адресованные конкретному пользователю - регистрация, восстановление пароля, уведомление о блокировке и т.д.
    • Периодические сообщения для группы пользователей - рассылки, подписка на комментарии и прочие
  4. Доставка сообщений может быть как по почте, так и через Jabber, ICQ, SMS и прочие
  5. Должна формироваться очередь отправки сообщений, позволяющая распределять загрузку по времени, чтобы не убивать канал отправки. Например, чтобы не попасть в spam-листы из-за большого количества исходящих сообщений.

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

Сервис сообщений должен состоять из двух частей:

  • Web-интерфейса для добавления сообщений в очередь, регистрации пользователей и подписок
  • Скрипта или демона для отправки сообщений

HTTP-интерфейс

HTTP-интерфейс используется сервисами для выполнения операций с пользователями и сообщениями. Интерфейс должен обладать следующим набором функций:

  • Добавление, изменение и удаление пользователя

    Очевидно, что для пользователя должны передаваться основные параметры, используемые при рассылке (полное имя, email, jabber и другие контактные данные), а так же дополнительные данные, которые могут быть использованы при формировании сообщений. Например, половая принадлежность, город проживания, дата рождения и прочие. Эти данные в Сервис сообщений могут передать различные сервисы. Например, паспорт может передать пол и возраст, а доска объявлений - количество добавленных пользователем объявлений. Данные пользователя привязываются к уникальному системному ID (в моем случае это ID пользователя в Паспорте)

  • Добавление пользователя в листы рассылки и удаление из них

    Фактически, листами рассылки может являться что угодно - почтовая подписка на новые материалы, уведомления о комментариях, сообщения в community, системные рассылки и так далее. Детали о том, что это за рассылка и каким образом она формируется, Сервиса сообщений не касаются - он занимается исключительно отправкой. Поэтому единственное что ему нужно знать о рассылке - это ее уникальный ID. В качестве такового можно использовать, например, комбинацию из названия сервиса и внутреннего ID объекта, к которому привязана рассылка. Например, уведомления о комментариях к статье номер 123 - publishing_article_123_comments, новые объявления раздела Недвижимость - classifieds_section_realty_ads.

  • Отправка персонального сообщения

    Сервис может отправить сообщение пользователю используя его уникальный системный ID. Сервису сообщений передается полный текст сообщения, при необходимости содержащий инструкции для вставки пользовательских данных, уже переданных другим сервисом (например, имени пользователя или его пола). Для обработки тела сообщения можно использовать обработчик шаблонов. Для этого хорошо подойдут Liquid и Radius. Обработка происходит непосредственно перед отправкой

  • Отправка сообщения для листа рассылки

    Сервис может добавить сообщение для листа рассылки, используя его уникальный ID (см. выше). Добавленное сообщение прогоняется через обработчик шаблонов для каждого пользователя, подписанного на рассылку, и результирующее сообщение ставится в общую очередь отправки.

  • Получение списка рассылок, на которые подписан пользователь

    Сервисы должны иметь возможность получить данные о том, на какие рассылки подписан пользователь. Данные используются для работы форм подписки на объекты в сервисах.

Скрипт рассылки

Чтобы разделить добавление и отправку сообщений, стоит вынести непосредственно рассылку в отдельный процесс. Запускать сервис можно как по крону (для небольших объемов сообщений), так в виде демона. Скрипт должен выполнять ряд функций, которые стоит вынести из HTTP-интерфейса:

  • Отправка сообщений

    Скрипт должен пачками забирать сообщения из очереди, отмечать их как находящиеся на обработке, а затем поочередно их отправлять используя указанные средства доставки - email, Jabber, ICQ или другие. В случае успешной отправки сообщения отмечаются как отправленные, в случае неудачи результат тоже сохраняется. Объем пакетов должен регулироваться для каждого средства доставки индивидуально.

  • Формирование очереди рассылок

    Сообщения для рассылок через HTTP-интерфейс только регистрируются, а непосредственно формирование текста сообщений индивидуально для каждого пользователя должно происходить в скрипте рассылки. Например, если сообщение было добавлено в рассылку с 3000 подписчиков, то формирование списка сообщений для отправки (с учетом обработки шаблонов для персонализации) может занять несколько десятков секунд, что явно не вписывается во временной лимит для HTTP-интерфейса.

  • Подключаемые средства отправки

    Если мы говорим не о узкоспециализированном сервисе, то необходимо учесть возможность добавления средств отправки в виде подключаемых плагинов или библиотек.

Технические средства

Для реализации HTTP-интерфейса можно использовать Rails или один из альтернативных Ruby-фреймворков. Для скрипта рассылки - rake (для запуска через cron), BackgroundRB, delayed_job или rudeq.

Что думаете по этому поводу?

Кофейные ссылки #2008-12-13

Опубликовано 13.12.2008

Нет ничего приятнее, чем хлебнуть кофейку суботнним утром. Сегодня ссылки у нас исключительно русскоязычные:

Кофейные ссылки #2008-12-11

Опубликовано 11.12.2008

Давненько не было у нас выпусков Кофейных ссылок, пора восстанавливать справедливость. Интересное на сегодня:

Кратко о проектах

Опубликовано 09.12.2008

Я последние несколько месяцев занимаюсь разработкой системы управления информационными порталами. Буквально несколько дней назад открыли в общий доступ один из клиентских проектов - портал МедиаЗавод, дочерний проект ООО “ЧР-Менеджер” (газеты Челябинский Рабочий, Тумба и еще несколько газет Челябинской области).

Проект сделан на рельсах, используется Single Sign-on для единой авторизации на всех сервисах. Всего в портал пока что включены 4 сервиса - система публикаций, доска объявлений, паспорт и баннерная система. Сервисы включают от 4 до 10 desert-модулей. В качестве JavaScript-библиотеки используется jQuery.

В системе публикаций используется упрощенная разметка Textile. Система администрирования интегрируется напрямую в дизайн, управляющие элементы при авторизации появляются прямо на страницах портала.

Развертывается все под nginx+passenger, используется кэширование в статику и вставка блоков через SSI. Сессии хранятся в memcache, через него же передается единая авторизацая.

Перехожу на jQuery

Опубликовано 05.12.2008

Получив суровый опыт Rails Rumble, я задумался над тем, какие инструменты я использую в своих проектах. Главным претендентом на увольнение стал Prototype: меня начал откровенно злить тот факт, что на его базе написано крайне мало удобных расширений, а в написанных разбираться реально только после поллитры.

Во время рамбла я сильно удивился тому, как легко и просто оказалось интегрировать jQuery с уже работающим на тот момент Prototype. После возвращения из Омска я покопался в интернете и нашел шикарнейшую статью, дающую базовое представление о принципах работы с jQuery. И я начал экспериментировать.

Для начала подключил его в административных интерфейсах в бесконфликтном режиме, параллельно с Prototype, и начал переписывать интерактивные элементы управления. Затем точно так же поступил с пользовательским интерфейсом. Какое-то время пришлось таскать за собой одновременно и Prototype, и jQuery, но этот период продлился недолго. Буквально два дня назад я окончательно убил Prototype.

Впечатления от новой игрушки самые радостные: я понимаю что и как нужно делать :) За все время работы с Prototype я не написал ни одного расширения - не знал с какой стороны подобраться. За время миграции на jQuery накатал уже 3 - настолько это оказалось просто. Плюс очень сильно радует разница в подходе к решению проблемы поиска готовых расширений: для Prototype приходится насиловать гугль чтобы найти хотя бы одно, а для jQuery - выбирать среди десятка вариантов тот, который подойдет наилучшим образом. А если не нашлось - можно просто написать свое.

Так что всем советую как минимум ознакомиться со следующими ссылками:

Парсинг даты/времени и значение по умолчанию

Опубликовано 27.11.2008

Хочется парсить дату/время из строки и в случае некорректного формата просто выдавать значение по умолчанию. Сделал такой вот маленький модуль:

module DateTimeParseWithDefault
  def parse_or_default(*args)
    default = args.pop
    begin
      parse(*args)
    rescue
      default
    end
  end
end

Date.extend(DateTimeParseWithDefault)
Time.extend(DateTimeParseWithDefault)

Использование:

@date = Date.parse_or_default(params[:date], Date.today)
@time = Time.parse_or_default(params[:time], Time.now - 1.month)

Вышел NetBeans 6.5

Опубликовано 24.11.2008

Толя буквально только что порадовал новостью: вышел в свет NetBeans 6.5

В новой версии:

  • Поддержка PHP (привет братьям нашим меньшим)
  • Поддержка Groovy и Grails (привет братьям по разуму)
  • Улучшена поддержка JavaScript, AJAX и Ruby (привет и нам тоже :)
  • Много изменений для улучшения жизни Java-разработчиков (не будем вникать)

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

Сейчас качаю. Чего и вам от всей души желаю.

Radiant CMS - в массы!

Опубликовано 18.11.2008

К системе управления сайтами Radiant CMS я присматривался давно, фактически с самого начала ее существования. Впервые познакомившись с ней, я подумал “Что за бред?” и не стал заморачиваться углубленным изучением. Однако, не так давно я повторно занялся ознакомлением с ее возможностями. И мне, честно говоря, понравилось то, с какой легкостью на ней создаются сайты для небольших компаний.

Если не обращать внимания на код, то система в целом сделана очень грамотно. Поддержка расширений, вполне удобный админский интерфейс, специальный язык разметки Radius - все это вкупе дает возможность практически неограничено расширять функционал сайта, добавляя все новые и новые фичи и интегрируя их в уже существующие страницы. Я решил, что такой системой не грех воспользоваться в своих целях.

Еще будучи соучередителем студии, ныне почившей, я много думал о том, как принести услугу по созданию сайтов в широкие массы. Хороший сайт раньше могла себе позволить, прямо скажем, не всякая компания. Для этого надо было расстаться с 50 а то и 100 тысячами рублей, что, согласитесь, весьма накладно. Для многих компаний это неподъемная цифра. Соответственно, продать такой товар было проблемно - люди просто не понимают, как нечто нематериальное может стоить таких бешеных денег.

Для начинающего непмана 21 века нужно что? Нужно страничку с описанием продаваемых рогов и копыт, прайсом, телефонами и формой для отправки сообщения. Вываливать за такое скромное удовольствие несколько десятков тысяч просто глупо и дураков среди нэпманов находится мало. Средним компаниям этого уже не достаточно, им надо чтоб интернет-магазин, чтоб обязательно форум и личный кабинет, поиск и Бог знает чего еще. А это все приближает стоимость к сотне тысяч или даже выходит за ее рамки, что тоже далеко не каждая контора осилит. Вытянут только крупные. А крупных считанные единицы, у большинства из них уже есть сайты и переделывать их никому не в кайф.

Во время одного из брифингов на тему “как увеличить доход” я предложил идею малобюджетных сайтов. Суть идеи в том, что клиенту не нужно платить за эксклюзивный дизайн, индивидуально заточенную систему администрирования и прочую атрибутику элитных веб-новостроек. Вместо хором класса ультра-супер-люкс-экстра-плюс клиент получает добротную веб-избушку с опрятным внешним видом и аскетичным внутренним убранством, не блистающим роскошью и завитушками, но вполне пригодным для повседневной жизни. Такой сайт решает проблему присутствия в сети и при этом не создает проблем с жабой.

Такова была первоначальная идея. Надо сказать, она не вызвала бурного восторга среди акционеров. Напротив, была принята стратегия увеличения цен, наращивания слоя понтов имиджа и создания московского представительства.

Однако, идея мне показалась настолько актуальной, что я решил ее не выбрасывать, а положить в долгий ящик и дать ей настояться. И вот буквально пару недель назад я наконец решил выволочь ее на свет божий, стряхнуть пыль и вдохнуть в нее жизнь.

Встречайте: Создание сайтов за 6999 рублей и 3 рабочих дня от компании IT Вектор

В предлагаемый комплект услуг я постарался вложить те технологии и инструменты, которые сам использую каждый божий день - CMS на базе Ruby on Rails, готовые дизайны с CSS-версткой и сервисы Google. Думаю, объем пакета будет постепенно расширяться, вбирая в себя все больше интерактивных сервисов, которые позволят частично перенести бизнес в сеть и сделать его более прозрачным.

Если у вас есть знакомые нэпманы, то вам это может принести вкусный и приятный бонус - у нас предусмотрена партнерская программа :)

Интервью на rubymag

Опубликовано 04.11.2008

Александр Сулим взял у меня интервью об участии в Rails Rumble для журнала rubymag. Не скажу что я проявил свое ораторское искусство во всей красе, но послушать вполне можно.

[ANN] Furwall - prevents unauthorized access

Опубликовано 01.11.2008

Давно у меня зрела идея сделать управление правами для доступа к объектам через БД. На досуге наконец оформил идею в плагин. Приветствуем Furwall - плагин для ограничения доступа к объектам:

script/plugin install git://github.com/dekart/furwall.git

Далее читаем README.

Это пока что концепт, поэтому любая конструктивная критика приветствуется. В особенности критика в виде патчей :) Обсудить можно тут.