EzDevInfo.com

ice_cube

Ruby Date Recurrence Library - Allows easy creation of recurrence rules and fast querying Ice cube by seejohnrun

IceCube/Ruby A rule for every 1 month and 10 days

Is it possible to make a rule like every 1 month and 10 days? Obviously 40 days isn't correct since months have a variable number of days in them, and it isn't by day of month or a particular day of the week?

Something that would generate:

1/01/2014
2/10/2014
3/20/2014
4/30/2014
6/09/2014

Source: (StackOverflow)

Create combinatorial schedule rules with ice_cube gem

Lets say I want a task to be scheduled every 6 hours on one day a week, every 2 weeks. How would I achieve this? I've used hour_of_day to add a specific hour to a weekly rule, but I'd like to avoid having to calculate each specific hour based off of the interval and start time, and adding them individually. Is it possible to chain rules? Like an hourly rule on top of a weekly one? When I add them as two separate rules, the hourly one fires independent of the weekly one, i.e. on days that wouldn't satisfy the weekly rule.


Source: (StackOverflow)

Advertisements

Ice_cube gem and find method in Rails 3

I'm using Ice_cube gem to generate events, and looks fine. The model that implements the recurrency is called "Job" , now I have a list of job, using pagination. I need to sort the Jobs in the list using the next events. The problem is that I'm using find method and will paginate to obtain the jobs . So my question is hoy I can sort the jobs , using the next event like parameter ?

Thanks.


Source: (StackOverflow)

How to integrate Ice Cube gem in rails app?

I have Event model(title,user,desciption,date_begin,date_end,repeat(daily, weekly, etc.))

 class Event < ActiveRecord::Base
  belongs_to :user
  include IceCube
end

What are the next steps for recurring events and their output? for example repeat = daily


Source: (StackOverflow)

ice_cube and recurring_select gems and occurrences

I'm attempting to utilize the [awesome] functionality of ice_cube and recurring_select gems to handle recurring events. I've got a schedule (text) column in my database and the following in the event model:

  def schedule=(new_schedule)
    write_attribute(:schedule, RecurringSelect.dirty_hash_to_rule(new_schedule).to_yaml)
  end

  def converted_schedule
     Schedule.from_yaml(self.schedule, :start_date_override => self.start_date)
  end 

Looking at the schedule column in psql, it appears to be storing the schedule correctly.

Here's my form:

.control-group
  = f.label 'Date', :class => 'control-label'
  .controls
    = f.text_field :start_date, :class => 'datepicker'

.control-group
  = f.label 'Recurring?', :class => 'control-label'
  .controls
    = f.select_recurring :schedule, :allow_blank => true

However, when I attempt to output converted_schedule, it only shows the start date and won't show any additional dates. I have a few suspicions that I've tinkered with no success... perhaps the YAML isn't being converted correctly for the converted_schedule method? Perhaps I need an end-date (I don't see where this functionality is available on recurring_select)?


Source: (StackOverflow)

Efficiently retrieving ice_cube schedules for a given time period

I'm looking into using Ice Cube https://github.com/seejohnrun/ice_cube for recurring events. My question is, if I then need to get any events that fall within a given time period (say, on a day or within a week), is there any better way than to loop through them all like this:

items = Records.find(:all)
items.each do |item|
  schedule = item.schedule
  if schedule.occurs_on?(Date.new)
      #if today is a recurrence, add to array
  end
end

This seems horribly inefficient but I'm not sure how else to go about it.


Source: (StackOverflow)

Using ice_cube Ruby gem in IRB

I'm trying to use a Ruby gem called ice_cube in IRB, but it doesn't work:

[~]$ rvm gemset create ice
'ice' gemset created (/home/joe/.rvm/gems/ruby-1.9.2-p320@ice).

[~]$ rvm gemset use ice
Using ruby-1.9.2-p320 with gemset ice

[~]$ gem install ice_cube
Fetching: ice_cube-0.8.0.gem (100%)
Successfully installed ice_cube-0.8.0
1 gem installed
Installing ri documentation for ice_cube-0.8.0...
Installing RDoc documentation for ice_cube-0.8.0...

[~]$ irb --simple-prompt
>> require 'ice_cube'
=> true

>> schedule = Schedule.new(Time.now)
NameError: uninitialized constant Object::Schedule
    from (irb):2
    from /home/joe/.rvm/rubies/ruby-1.9.2-p320/bin/irb:16:in `<main>'

What am I doing wrong? (I'm a beginner Ruby programmer.)


Source: (StackOverflow)

gem ice_cube for reccurence events

I have simple Event model (title, date, user) And I created Events Calendar by months (gem 'watu_table_builder'). I need the feature to create repeating events. I figured out that I may use gem ice_cube for it. But it is not clear for me.

I added to model:

class Event < ActiveRecord::Base
  #require 'ice_cube'
  include IceCube

  belongs_to :user

  validates :title, :presence => true,
                    :length => { :minimum => 5 }
  validates :shedule, :presence => true

  def self.events_and_repeats(date)
    @events = Event.where(shedule:date.beginning_of_month..date.end_of_month)

# Here I need to figure out what is events repeats at this month (from date param)
# how I may combine it with Events array

    @events_repeats = @events # + repeats

    return @events_repeats

  end

1) How I may combine repeat rules with Events array?

2) As I understand, I may save to db information about repeats in yaml yaml = schedule.to_yaml

But it is not clear for me how it is good way to create drop-down for repeats (none, each day, each month, each year) and link it with shedule rules. Where and how I should realize it (convert user choise to right shedule)


Source: (StackOverflow)

Single occurrence event with ice_cube gem using start_time and end_time

There must be something simple being overlooked here...

I've been trying various methods for creating a basic IceCube schedule (https://github.com/seejohnrun/ice_cube). The overall goal is to use IceCube to allow "price schedules" inside a "room reservation" rails application.

The first scenario would be creating a basic schedule with a specific start_time and end_time - occurring only once. IceCube can do this, correct?

The schedule would begin on the start_time and end at the end_time. I would expect to be able to check if dates or times occurs_on? this schedule to determine if a room price should be adjusted.

So in console I've tried creating a basic schedule and would expect it to be occurring 5.days from now since the start_time is Time.now and the end_time is Time.now + 30.days. But it seems to never return true...

1.8.7 :001 > schedule = IceCube::Schedule.new(Time.now, :end_time => Time.now + 30.days)
 => #<IceCube::Schedule:0xb619d604 @all_recurrence_rules=[], @duration=nil, @end_time=Tue Jan 08 09:13:11 -0600 2013, @all_exception_rules=[], @start_time=Sun Dec 09  09:13:11 -0600 2012> 
1.8.7 :002 > schedule.occurs_on? Date.today + 5.days
 => false 
1.8.7 :005 > schedule.occurs_at? Time.now + 5.days
 => false 
1.8.7 :006 > schedule.occurring_at? Time.now + 5.days
 => false 

Adding a recurrence rule

1.8.7 :018 > schedule.rrule IceCube::Rule.monthly
=> [#<IceCube::MonthlyRule:0xb687a88c @validations={:base_day=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875b0c @type=:day>], :base_hour=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875abc @type=:hour>], :interval=>[#<IceCube::Validations::MonthlyInterval::Validation:0xb6875d28 @interval=1>], :base_min=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875a6c @type=:min>], :base_sec=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875a1c @type=:sec>]}, @interval=1>] 

Then checking Date.today works...

1.8.7 :025 > schedule.occurs_on? Date.today
 => true 

But checking occurs_on? for Date.today + 10.days still returns false... Why?

1.8.7 :026 > schedule.occurs_on? Date.today + 10.days
 => false 

So what am I overlooking / doing wrong? Or what is the point of setting an IceCube::Schedule start_time and end_time - they seem to have no effect...?

Does IceCube not work for single occurrence events with a start and end time?

Another example scenario, a room owner wants room prices raised for a holiday season. So the room owner creates a price schedule that starts on Dec 1 2012 and ends Jan 7 2013. (shouldn't have to recur, but could if the owner wanted).

Then when people are searching rooms, the prices would be adjusted if the requested stay occurs_on? a holiday price schedule

Do I need to store the start_time and end_time outside of the schedule and check it manually or something?

Or is there a better suited gem / tool to assist with this kind of schedule management?


Source: (StackOverflow)

Identify the ice_cube schedule

i would like to identify the details of an schedule. e.g:

i have the schedule for an event: event.schedule

"Every 3 months on the 10th day of the month"

represented by the hash:

  {
   :start_date=>2012-02-06 10:37:04 +0100, 
   :rrules=>[{
     :validations=>{
       :day_of_month=>[10]}, 
       :rule_type=>"IceCube::MonthlyRule", 
       :interval=>3
    }], 
    :exrules=>[], :rdates=>[], :exdates=>[] 
  }

to set the specific form elements (dropdown, checkbox) i need to evaluate the specific rules. e.g. for

  event.schedule.interval 

i would expect

  IceCube::MonthlyRule

i did not found any methods in the source, does somebody did sth. similar ? My approach would be to parse the hash and extract every rule...


Source: (StackOverflow)

creating recurring events with ice_cube gem

I am trying to create recurring events using ice_cube and recurring_select gems.

Here is my _form.html.erb code:

<%= simple_form_for(@event) do |f| %>
  <div class="form-inputs">
    <%= f.select_recurring :day, [IceCube::Rule.daily]  %>
    <%= f.input :start_time %>
    <%= f.input :end_time %>
  </div>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

In my controller I have (among other things):

def new
   @event = Event.new
end

def create
  @event = Event.new(event_params)
  respond_to do |format|
    if @event.save
      format.html { redirect_to @event, notice: 'Event was successfully created.' }
      format.json { render :show, status: :created, location: @event }
    else
      format.html { render :new }
      format.json { render json: @event.errors, status: :unprocessable_entity }
    end
  end
end

def event_params
  params.require(:event).permit(:day, :start_time, :end_time, :reserved)
end

As you can see I want to create the same event for each day in a week, but actually my :day column remains empty if I submit this form.

Can you give some feedback? I don't know what can be wrong


Source: (StackOverflow)

Calculate the intersection of two arrays of ranges (of dates) in ruby

Given two large arrays of ranges...

A = [0..23, 30..53, 60..83, 90..113]
B = [-Float::INFINITY..13, 25..33, 45..53, 65..73, 85..93]

When I do a logical conjuction...

C = A.mask(B)

Then I expect

describe "Array#mask" do
  it{expect(C = A.mask(B)).to eq([0..13, 30..33, 45..53, 65..73, 90..93])}
end

It feels like it should be...

C = A & B
=> []

but that's empty because none of the ranges are identical.

Here's a pictorial example.

Logical conjuction waveform.

I've included Infinity in the range because solutions to this problem typically involve converting the Range to an Array or Set.

My current solution This is my current solution with passing tests for speed and accuracy. I was looking for comments and/or suggested improvements. The second test uses the excellent IceCube gem to generate an array of date ranges. There's an implicit assumption in my mask method that date range occurrences within each schedule do not overlap.

require 'pry'
require 'rspec'
require 'benchmark'
require 'chronic'
require 'ice_cube'
require 'active_support'
require 'active_support/core_ext/numeric'
require 'active_support/core_ext/date/calculations'

A = [0..23, 30..53, 60..83, 90..113]
B = [-Float::INFINITY..13, 25..33, 45..53, 65..73, 85..93]

class Array
  def mask(other)
    a_down = self.map{|r| [:a, r.max]}
    a_up = self.map{|r| [:a, r.min]}

    b_down = other.map{|r| [:b, r.max]}
    b_up = other.map{|r| [:b, r.min]}

    up = a_up + b_up
    down = a_down + b_down

    a, b, start, result = false, false, nil, []
    ticks = (up + down).sort_by{|i| i[1]}
    ticks.each do |tick|
      tick[0] == :a ? a = !a : b = !b
      result << (start..tick[1]) if !start.nil?
      start = a & b ? tick[1] : nil
    end
    return result
  end
end

describe "Array#mask" do
  context "simple integer array" do
    it{expect(C = A.mask(B)).to eq([0..13, 30..33, 45..53, 65..73, 90..93])}
  end

  context "larger date ranges from IceCube schedule" do
    it "should take less than 0.1 seconds" do
      year = Time.now..(Time.now + 52.weeks)
      non_premium_schedule = IceCube::Schedule.new(Time.at(0)) do |s|
        s.duration = 12.hours
        s.add_recurrence_rule IceCube::Rule.weekly.day(:monday, :tuesday, :wednesday, :thursday, :friday).hour_of_day(7).minute_of_hour(0)
      end
      rota_schedule = IceCube::Schedule.new(Time.at(0)) do |s|
        s.duration = 7.hours
        s.add_recurrence_rule IceCube::Rule.weekly(2).day(:tuesday).hour_of_day(15).minute_of_hour(30)
      end
      np = non_premium_schedule.occurrences_between(year.min, year.max).map{|d| d..d+non_premium_schedule.duration}
      rt = rota_schedule.occurrences_between(year.min, year.max).map{|d| d..d+rota_schedule.duration}
      expect(Benchmark.realtime{np.mask(rt)}).to be < 0.1
    end
  end
end

It feels odd that you can't do this with Ruby's existing core methods? Am I missing something? I find myself calculating range intersections on a fairly regular basis.

It also occurred to me that you could use the same method to find an intersection between two single ranges by passing single item arrays. e.g.

[(54..99)].mask[(65..120)]

I realise I've kind of answered my own question but thought I would leave it here as a reference for others.


Source: (StackOverflow)

Opening hours in ice_cube

How am I able to rule opening hours of a restaurant within single Schedule?

Mon-Fri 8-16 is quite easy:

schedule = Schedule.new(Time.parse(Date.yesterday.to_s + ' 8:00'), :duration => 60*60*8)
(...)
schedule.add_recurrence_rule Rule.daily.day(:wednesday)
schedule.add_recurrence_rule Rule.daily.day(:thursday)
(...)
schedule.occurring_at?(Time.now)

Problem is when trying to rule something like: Mon 9-17, Tu 16-01 (the next day after midnight) etc.

Am I able to do this with that plugin?


Source: (StackOverflow)

Recurring events on event_calendar

I am trying to implement recurring events for event_calendar and it is turing out to be quite challenge. It seem I have to write the recurrence for my events from scratch. I have no problem with that as long as I am not missing a better way of doing it that has already been implemented and that I could potentially even contribute to.

How did or do you recommend implementing recurring events for a calendar such as event_calendar?

If I have to start from scratch what advices could you give? Would you use Ice_cube? Can you describe your approach? Thank you so much.


Source: (StackOverflow)

Ruby/ice_cube: Exclude whole day for hourly recurring event

Just started playing around with ice_cube I've got a weekly schedule (with a granularity of half an hour) created

schedule = IceCube::Schedule.new(Time.now.change(:min => 30))

with several rules (let's say 20) such as e.g.

IceCube::Rule.weekly.day(:tuesday).hour_of_day(14).minute_of_hour(30)

or

IceCube::Rule.weekly.day(:wednesday).hour_of_day(10).minute_of_hour(0)

Now I'd like to exclude a full day, which would subsequently exclude all occurrences during this full day.

I've tried

schedule.add_exception_date [DATE]

but it seems that my exception has to match the event exactly.

Is there a way to get this done without looping through all rules and creating exception for the exact times for the date specified?


Update:

To make a better example:

Weekly schedule:
  * Every monday at 14:40
  * Every monday at 15:00
  * Every thursday at 16:00 
  * Every saturday at 10:00

Exception date:
  Tuesday, 13th of September 2011

=> For the week from Monday 12th to Sunday 18th I'd like to get only the occurrences on Thursday and Saturday.

One solution could look something like this, but it's a little icky:

schedule    = IceCube::Schedule.from_yaml([PERSISTED SCHEDULE])
occurrences = schedule.occurrences_between([START TIME], [END TIME])
exceptions  = schedule.exdates.map(&:to_date)
occurrences.reject {|occurrence|
  exceptions.include?(occurrence.to_date)
}

—Any better ideas?


Source: (StackOverflow)