Ruby: опыт работы с Gems для повторяющихся событий календаря? - PullRequest
14 голосов
/ 14 марта 2011

Я хочу найти рубиновый драгоценный камень для моего проекта для работы с событиями повторного получения, которые соответствуют следующим требованиям:

  • может обрабатывать шаблоны типа «Еженедельно во вторник и субботу» или «Ежемесячно в последний»Вторник "
  • может вычислить следующий случай
  • может сериализовать / десериализовать шаблон в строку для хранения в базе данных
  • сериализация имеет стабильный формат (например, она сможет загружаться даже после
  • работает как минимум со следующими компонентами шаблона: время, день недели, дата месяца, n-й день недели в месяце;
  • может повторяться ежедневно, еженедельно, ежемесячно или с интерваломn дней, недель или месяцев
  • может представлять шаблон на естественном английском языке
  • может анализировать шаблон с английского (необязательно)
  • может экспортировать в какой-либо популярный формат, такой как iCal (необязательно)
  • может интегрироваться с другими гемами / системами для управления календарем и задачами (необязательно)
  • поддержка Active Record - анализ параметров, валидацияIon (опционально)
  • имеет достаточно тестов и несколько ошибок, более одного пользователя :)
  • имеет разумную производительность

Я нашел двух подходящих кандидатов:

  • Щекотка - польза в том, что он может разбирать английский.
  • Ice_Cube (+ Schedule-Attributes) - хорошо, что он наиболее популярен и может экспортироваться в iCal

Не могли бы вы предложить драгоценный камень и описать положительный и отрицательный опыт работы с ним?

Может быть, вы также могли бы добавить некоторые соответствующие критерии / требования, которые я не упомянул.

PS Pease кто-то с 1,5K + добавить тег recurring_events.Спасибо

Ответы [ 4 ]

8 голосов
/ 19 апреля 2011

Я использую Ice_Cube по следующим причинам:

  • Самые популярные
  • могут вычислить следующий случай
  • может сериализовать / десериализовать шаблон в строку для хранения в базе данных
  • сериализация имеет стабильный формат (например, она сможет загружаться даже после обновления)
  • работает как минимум со следующими компонентами шаблона:Время, день недели, дата месяца, n-й день недели в месяце;
  • может повторяться ежедневно, еженедельно, ежемесячно или с интервалом n дней, недель или месяцев
  • может анализировать схемус английского (опционально)
  • можно экспортировать в какой-нибудь популярный формат, например iCal (опционально)

Эти критерии не соответствуют моим требованиям:

  • может представлять шаблон на естественном английском языке
  • поддержка Active Record - анализ параметров, проверка (необязательно)

Этот файл не проверен:

  • имеет разумную производительность

Создание льда_Cube :: Расписание из пользовательского ввода в Rails не очень удобно, но выполнимо:

class EntryForm < FormModel

  include IceCube
  class_eval &ValidatesTimelinessSupport[{:start_date => :datetime}]

  Units = [Day = 'day', Week = 'week']
  Intervals = %w[0 1 2 3 4 5 6 7 8 9]
  Week_Days = [:sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday]

  Days_With_Letters = Week_Days.zip(%w[S M T W T F S])

  attr_accessible_accessors :interval, :unit, :start_date
  attr_accessible_accessors *Week_Days

  def_delegators :@model, :display_title, :schedule_yaml, :schedule_yaml=

  validates_date :start_date, :allow_blank => true
  validates_inclusion_of :unit, :in => Units
  validates_inclusion_of :interval, :in => Intervals
  validates_inclusion_of :complete, :in => %w[0 1], :allow_blank => true
  Week_Days.each { |day| validates_inclusion_of day, :in => %w[0 1], :allow_blank => true }

  before_edit {
    if not schedule_yaml.blank? and hash = YAML::load(schedule_yaml)
      schedule = Schedule.from_hash(hash)
    end

    if schedule and rule = schedule.rrules.first
      @start_date = schedule.start_date

      rule_hash = rule.to_hash
      @interval = rule_hash[:interval]

      case rule
      when DailyRule
        @unit = Day
      when WeeklyRule
        @unit = Week
        rule_hash[:validations][:day].try :each do |day_index|
          send "#{Week_Days[day_index]}=", 1
        end
      end

    else
      @start_date = Date.today
      @interval = 1
      @unit = Day
    end
  }

  before_save {
      sd = @start_date.blank? ?
          Date.today.to_all_day :
          @start_date.parse_date_in_timezone
      i = @interval.to_i
      schedule = Schedule.new(sd)


      rule = case @unit
        when Day
          Rule.daily i
        when Week
          Rule.weekly(i).day(
            *Week_Days.
            select { |day| send(day).to_i == 1 } )
      end

      schedule.add_recurrence_rule(rule)

      self.schedule_yaml = schedule.to_yaml
    end
  }
end
7 голосов
/ 09 августа 2011

Как бы ни был хорош Ice_Cube, он не подходит для крупномасштабных приложений планирования, где у вас может быть более 100 000 событий, которые необходимо отфильтровать, чтобы увидеть то, что появляется в текущий день. Подумайтеmeetup.com

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

def self.entries_on(date)
    entries = TimetableEntry.all
    entries.reject{|te|!te.schedule.occurs_on?(date)}
end

Не очень эффективно.Кто-то, пожалуйста, исправьте меня!надеюсь, я упустил хитрость?

Также попробуйте описанный выше метод с датой, которой в будущем будет 100 лет ... кажется, что ice_cube замедляется по мере удаления от текущей даты.

2 голосов
/ 27 марта 2012

Я рекомендую взглянуть на RubyToolbox Повторяющиеся события драгоценные камни.Это должно быть в курсе и включает ice_cube, упомянутый ранее.

2 голосов
/ 15 марта 2011

Я не знаю ни одного плагина, который бы отвечал всем вашим требованиям, но комбинация rufus-scheduler и Хронический должна вывести вас довольно далеко.

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

В документации Rufus есть несколько примечаний по сопряжению двух решений.

...