kalindar 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODM4YWQ2ZWIxNzE4NjA1NmZlZmY0NDBhM2QwMTQ1ZWNmMzBlNTg2NQ==
4
+ ZWU3MDYxNDY1NDhmMjQ1MTcxZDgxNDgwNGY4NDcxNDJiYTk3NGM1MQ==
5
5
  data.tar.gz: !binary |-
6
- Y2E2ZWNiYmI1YmU2NjNkZTdjNzFkZWI4NjEwNTRhNDBiMjBlODdjZA==
6
+ ZmMzMzNkNmMyOGMyYmEyYWU1MzQyY2EwYmQyZDQyMGQ5MmM1N2UzOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- N2JjZDQ1MWY1Mzk3OWVmODExYjNmMmU2NDEyMTNjNzFlYTFiYzA5YjRlNTQz
10
- ODJmMDNiNzViYzNjZWRkNWU4OWYwYThjN2M3NDVmY2Q5YTQzN2VjMzljMmVm
11
- OTFkMjg1YWFhZjNiMTZkOTcxNTYyY2Q5YmJjNjQ0OWJmOWZkYTA=
9
+ MzQ3M2Q5ZTFhZGNhMmExYTkzOTNjZmQ0NWVhMzkxZGY1OTdjZjNkYmNjYTY4
10
+ NDA1ZmM1YjkwZmVmNDY4ZmYxMzRmN2Y2MTk3NmFlYzVlMmQ1Nzk4NzliOWRj
11
+ ZjMzMjA3ZDFmNTkzZGM0M2VlZDI4ZjlhMTdkN2IxYTQ2NjZlZTg=
12
12
  data.tar.gz: !binary |-
13
- MjRkYmNhYjE2YTg2Nzc2MDAyNTUzM2ExYjlhYzRjYmEwZWY5NjM3NTBlODY1
14
- M2U2ODVmZDRhNmU4Y2I0NjM3Y2VlZDdmNWVmNzc4Njk2ZjJiMTRmMDllOWIz
15
- M2JlZjk4ZDI1OTk4ZTE5ZDNhNWJlYjI4YmI5OWJlMjFjOTA4ZTg=
13
+ ZWI4OWM2NTZkNDY4YWQyZjk0OWU5ZGJkYjFkOGVjNTc0NTUzYjM5ODVkNzli
14
+ MzlkMjZlMzM0OGM2NDNhYzZjMDNiYjA5MmJjYmY4MjA3OWM1MDM1NjNkODVl
15
+ NTI3ZGI3MjQwMzgzMzQxZjIzOGU0NjZmZjY1MzRlYjJkNjQ0YWY=
data/README.md CHANGED
@@ -4,6 +4,8 @@ Kalindar lets you view ics files via a webbrowser.
4
4
 
5
5
  It employs the ri_cal, sinatra, i18n ruby gems, the rightjs JavaScript framework and the Pure CSS framework.
6
6
 
7
+ It shows recuring events and reloads on ics file changes.
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -32,7 +34,7 @@ Be careful. Kalindar might destroy, change or delete your ics file(s)!
32
34
 
33
35
  Kalindar does not care about timezones!
34
36
 
35
- Kalindar gets confused by re-occuring events!
37
+ Kalindar gets confused by re-occuring events, they are shown, but better do not modify.
36
38
 
37
39
  ### Configuration
38
40
 
data/lib/kalindar.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "kalindar/version"
2
+ require 'kalindar/timespan'
2
3
  require 'kalindar/event'
3
4
  require 'kalindar/calendar'
4
5
  require 'kalindar/event_calendar'
data/lib/kalindar/app.rb CHANGED
@@ -7,16 +7,17 @@ require 'i18n'
7
7
  require 'i18n/backend/fallbacks'
8
8
  require 'listen'
9
9
 
10
+ # Read in calendar files, fill global cal var.
11
+ def cals
12
+ EventCalendar.new($conf['calendar_files'])
13
+ end
14
+
15
+
10
16
  # Sinatra App for Kalindar, show ics files.
11
17
  class KalindarApp < Sinatra::Base
12
18
  $conf = JSON.load(File.new('config.json'))
13
19
 
14
- # Read in calendar files, fill global cal var.
15
- def load_global_cal
16
- $cal = EventCalendar.new($conf['calendar_files'])
17
- end
18
-
19
- load_global_cal
20
+ $cal = cals
20
21
 
21
22
  configure do
22
23
  I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
@@ -29,7 +30,7 @@ class KalindarApp < Sinatra::Base
29
30
  path = Pathname.new(file).realpath
30
31
  dir = path.dirname.to_s
31
32
  base = path.basename.to_s
32
- listener = Listen.to(dir, only: /#{base}/) { load_global_cal }
33
+ listener = Listen.to(dir, only: /#{base}/) { $cal = cals }
33
34
  listener.start
34
35
  end
35
36
  end
@@ -62,37 +63,39 @@ class KalindarApp < Sinatra::Base
62
63
  end
63
64
 
64
65
  get '/events/:year/:month' do
65
- @events = {}
66
66
  # Events from start time to 31 days later
67
67
  date = Date.new(params[:year].to_i, params[:month].to_i, 1)
68
+
69
+ @events = $cal.events_in(date, date + 30)
70
+
71
+ # Pre-fill hash
68
72
  (date .. date + 30).each do |day|
69
- #@events[d] = $cal.events_for(d)
70
- @events[day] = $cal.find_events day.to_date
73
+ @events[day] ||= []
71
74
  end
75
+
72
76
  slim :event_list
73
77
  end
74
78
 
75
79
  get '/events' do
76
- @events = {}
77
- # events from today to in 30 days
80
+ # Events from today to in 30 days
81
+ @events = $cal.events_in(DateTime.now, DateTime.now + 30)
82
+
83
+ # Pre-fill hash
78
84
  (DateTime.now .. DateTime.now + 30).each do |day|
79
- #@events[d] = $cal.events_for(d)
80
- @events[day] = $cal.find_events day.to_date
85
+ @events[day] ||= []
81
86
  end
87
+
82
88
  slim :event_list
83
89
  end
84
90
 
85
91
  get '/events/twoday' do
86
- @events = {}
87
92
  # events from today to in 30 days
88
- (DateTime.now .. DateTime.now + 2).each do |day|
89
- #@events[d] = $cal.events_for(d)
90
- @events[day] = $cal.find_events day.to_date
91
- end
93
+ @events[day] = $cal.events_in DateTime.now, DateTime.now + 2
92
94
 
93
95
  #@events = @events.values.flatten.sort_by {|e| e.start_time}
94
96
  @today = Date.today
95
97
  @tomorrow = @today + 1
98
+
96
99
  slim :twoday_list
97
100
  end
98
101
 
@@ -1,110 +1,112 @@
1
1
  require 'delegate'
2
2
 
3
- # Delegator with some handy shortcuts
4
- class Event < SimpleDelegator
5
- # Time it starts at day, or '...'
6
- def start_time_f day
7
- #puts "start #{start_time} : #{start_time.class} #{start_time.to_date} #{day}"
8
- if dtstart.class == Date
9
- # whole day
10
- ""
11
- elsif start_time.to_date == day.to_date
12
- start_time.strftime('%H:%M')
13
- else
14
- "..."
3
+ module Kalindar
4
+ # Delegator with some handy shortcuts
5
+ class Event < SimpleDelegator
6
+ # Time it starts at day, or '...'
7
+ def start_time_f day
8
+ #puts "start #{start_time} : #{start_time.class} #{start_time.to_date} #{day}"
9
+ if dtstart.class == Date
10
+ # whole day
11
+ ""
12
+ elsif start_time.to_date == day.to_date
13
+ start_time.strftime('%H:%M')
14
+ else
15
+ "..."
16
+ end
15
17
  end
16
- end
17
-
18
- # Time it finishes at day, or '...'
19
- def finish_time_f day
20
- if dtend.class == Date
21
- # whole day
22
- ""
23
- elsif finish_time.to_date == day.to_date
24
- finish_time.strftime('%H:%M')
25
- else
26
- return "..."
18
+
19
+ # Time it finishes at day, or '...'
20
+ def finish_time_f day
21
+ if dtend.class == Date
22
+ # whole day
23
+ ""
24
+ elsif finish_time.to_date == day.to_date
25
+ finish_time.strftime('%H:%M')
26
+ else
27
+ return "..."
28
+ end
27
29
  end
28
- end
29
-
30
- # Time it finishes and or starts at day, or '...'
31
- def time_f day
32
- start = start_time_f day
33
- finish = finish_time_f day
34
- if start == finish && start == ""
35
- # whole day
36
- ""
37
- elsif start == finish && start == "..."
38
- "..."
39
- else
40
- "#{start_time_f day} - #{finish_time_f day}"
30
+
31
+ # Time it finishes and or starts at day, or '...'
32
+ def time_f day
33
+ start = start_time_f day
34
+ finish = finish_time_f day
35
+ if start == finish && start == ""
36
+ # whole day
37
+ ""
38
+ elsif start == finish && start == "..."
39
+ "..."
40
+ else
41
+ "#{start_time_f day} - #{finish_time_f day}"
42
+ end
41
43
  end
42
- end
43
-
44
- # Date and time from and to
45
- def from_to_f
46
- return "#{dtstart.to_datetime.strftime("%d.%m. %H:%M")} - #{dtend.to_datetime.strftime("%d.%m. %H:%M")}"
47
- end
48
-
49
- # Create DateTime from yyyymmdd + h + m .
50
- def self.start_time_from_params params
51
- start_day = Date.parse(params['start_day'])
52
- if !params[:start_time]
53
- return start_day
44
+
45
+ # Date and time from and to
46
+ def from_to_f
47
+ return "#{dtstart.to_datetime.strftime("%d.%m. %H:%M")} - #{dtend.to_datetime.strftime("%d.%m. %H:%M")}"
54
48
  end
55
-
56
- hour, minute = params[:start_time].match(/(\d\d):(\d\d)/)[1,2]
57
- start_time = DateTime.new(start_day.year,
58
- start_day.month, start_day.day, hour.to_i, minute.to_i)
59
- end
60
-
61
- def self.start_date_from params
62
- Date.parse(params['start_day'])
63
- end
64
-
65
-
66
- def update params
67
- begin
68
- hour, minute = params['start_time'].match(/(\d\d):(\d\d)/)[1,2]
49
+
50
+ # Create DateTime from yyyymmdd + h + m .
51
+ def self.start_time_from_params params
69
52
  start_day = Date.parse(params['start_day'])
53
+ if !params[:start_time]
54
+ return start_day
55
+ end
56
+
57
+ hour, minute = params[:start_time].match(/(\d\d):(\d\d)/)[1,2]
70
58
  start_time = DateTime.new(start_day.year,
71
59
  start_day.month, start_day.day, hour.to_i, minute.to_i)
72
- self.dtstart = start_time
73
- minutes = EventParamHelper.duration params['duration']
74
- self.dtend = start_time + Rational(minutes, 1440)
75
- rescue => e
76
- STDERR.puts "event#update params: problems with (up)date #{e.message}"
77
60
  end
78
-
79
- self.summary = params['summary'] if params['summary']
80
- self.description = params['description'] if params['description']
81
- self.location = params['location'] if params['location']
82
- end
83
-
84
- # Create a new event from params as given by new_event form of kalindar.
85
- # this should eventually go somewhere else, but its better here than in app already.
86
- def self.create_from_params params
87
- event = RiCal::Component::Event.new($cal.calendars.first)
88
- event.uid = SecureRandom.uuid
89
- if params['summary']
90
- event.summary = params['summary']
61
+
62
+ def self.start_date_from params
63
+ Date.parse(params['start_day'])
91
64
  end
92
- if params['description']
93
- event.description = params['description']
65
+
66
+
67
+ def update params
68
+ begin
69
+ hour, minute = params['start_time'].match(/(\d\d):(\d\d)/)[1,2]
70
+ start_day = Date.parse(params['start_day'])
71
+ start_time = DateTime.new(start_day.year,
72
+ start_day.month, start_day.day, hour.to_i, minute.to_i)
73
+ self.dtstart = start_time
74
+ minutes = EventParamHelper.duration params['duration']
75
+ self.dtend = start_time + Rational(minutes, 1440)
76
+ rescue => e
77
+ STDERR.puts "event#update params: problems with (up)date #{e.message}"
78
+ end
79
+
80
+ self.summary = params['summary'] if params['summary']
81
+ self.description = params['description'] if params['description']
82
+ self.location = params['location'] if params['location']
94
83
  end
95
- if params['location']
96
- event.location = params['location']
84
+
85
+ # Create a new event from params as given by new_event form of kalindar.
86
+ # this should eventually go somewhere else, but its better here than in app already.
87
+ def self.create_from_params params
88
+ event = RiCal::Component::Event.new($cal.calendars.first)
89
+ event.uid = SecureRandom.uuid
90
+ if params['summary']
91
+ event.summary = params['summary']
92
+ end
93
+ if params['description']
94
+ event.description = params['description']
95
+ end
96
+ if params['location']
97
+ event.location = params['location']
98
+ end
99
+
100
+ # Access should be made failsafe.
101
+ start_time = start_time_from_params(params)
102
+ event.dtstart = start_time
103
+ minutes = EventParamHelper.duration params['duration']
104
+ event.dtend = start_time + Rational(minutes, 1440)
105
+ Event.new event
97
106
  end
98
-
99
- # Access should be made failsafe.
100
- start_time = start_time_from_params(params)
101
- event.dtstart = start_time
102
- minutes = EventParamHelper.duration params['duration']
103
- event.dtend = start_time + Rational(minutes, 1440)
104
- Event.new event
107
+
108
+ private
105
109
  end
106
-
107
- private
108
110
  end
109
111
 
110
112
  module EventParamHelper
@@ -43,61 +43,53 @@ class EventCalendar
43
43
  end.flatten
44
44
  end
45
45
 
46
- def events_for_date date
47
- events = @calendars.map &:events
48
- events.select {|event| event_includes? event, date}.flatten
49
- events.map {|event|
50
- Event.new event
51
- }
52
- end
53
-
54
- # Nother optimization potential
55
- def events_per_day start_date, end_date
56
- map = {}
57
- (start_date .. end_date).each do |day|
58
- (map[day] ||= []) << find_events(day)
46
+ # start_date and end_date are inclusive,
47
+ # start_date can be Timespan, too
48
+ def events_in start_date, end_date=nil
49
+ if end_date.nil? && !start_date.is_a?(Timespan)
50
+ timespan = Timespan.day_end start_date
51
+ end_date = timespan.finish
52
+ start_date = timespan.start
53
+ end
54
+ if start_date.is_a? Timespan
55
+ timespan = start_date
56
+ end_date = start_date.finish
57
+ start_date = start_date.start
59
58
  end
60
- map
61
- end
62
59
 
63
- # Best optimization potential
64
- def events_in start_date, end_date
65
- events = []
66
- (start_date .. end_date).each do |day|
67
- events << find_events(day)
60
+ # All overlapping occurences.
61
+ occurrences = events.map do |e|
62
+ e.occurrences(:overlapping => [start_date, end_date])
68
63
  end
69
- events.flatten
70
- end
71
64
 
72
- # Find (non-recuring) events that begin, end or cover the given day.
73
- def find_events date
74
- #events = @calendars.map &:events
75
- @calendars.map do |calendar|
76
- calendar.events.select { |event|
77
- # If end-date is a Date (vs DateTime) let it be
78
- # All day/multiple day events
79
- if event.dtstart.class == Date && event.dtend.class == Date
80
- event.dtstart.to_date == date || (event.dtstart < date && event.dtend > date)
81
- else
82
- event.dtstart.to_date == date || event.dtend.to_date == date || (event.dtstart < date && event.dtend > date)
83
- # occurrences need to be re-enabled
84
- #||!event.occurrences(:overlapping => [date, date +1]).empty?
65
+ # Collect occurences by date.
66
+ hash = occurrences.inject({}) do |hsh, o|
67
+ o.each do |oc|
68
+ event = Kalindar::Event.new(oc)
69
+ (oc.dtstart.to_date .. oc.dtend.to_date).each do |day|
70
+ # Strip timerange and exclude one-and-whole-day events (they "end" next day).
71
+ if day >= start_date && day <= end_date && !(oc.dtstart != oc.dtend && oc.dtend.class == Date && oc.dtend == day)
72
+ (hsh[day] ||= []) << event
73
+ end
85
74
  end
86
- }
87
- end.flatten.map do |event|
88
- Event.new event
75
+ end
76
+ hsh
89
77
  end
90
- # check flat_map enumerable method
78
+ hash
91
79
  end
92
80
 
93
81
  def find_by_uid uuid
94
82
  # we want to pick only the first! whats the method? detect is one, find another
95
83
  @calendars.map(&:events).flatten.each do |event|
96
- return Event.new(event) if event.uid == uuid
84
+ return Kalindar::Event.new(event) if event.uid == uuid
97
85
  end
98
86
  nil
99
87
  end
100
88
 
89
+ def events
90
+ @calendars.map(&:events).flatten
91
+ end
92
+
101
93
  private
102
94
 
103
95
  def dtmonth_start year, month
@@ -124,5 +116,3 @@ class EventCalendar
124
116
  incl
125
117
  end
126
118
  end
127
-
128
-
@@ -37,3 +37,9 @@
37
37
  onFailure: function(resp) {alert(resp.responseText);},
38
38
  });
39
39
  });
40
+
41
+ /* Refresh every 5 minutes. */
42
+ var refresh = function () {
43
+ location.reload();
44
+ }
45
+ refresh.periodical(1000 * 60 * 5);
@@ -0,0 +1,22 @@
1
+ require 'time'
2
+
3
+ class Timespan
4
+ attr_accessor :start
5
+ attr_accessor :finish
6
+ def initialize start, finish
7
+ @start = start
8
+ @finish = finish
9
+ end
10
+
11
+ def self.from_day date
12
+ start = DateTime.new date.year, date.month, date.day, 0, 0
13
+ finish = DateTime.new date.year, date.month, date.day, 23, 59
14
+ Timsepan.new start, finish
15
+ end
16
+
17
+ # Return Timespan from start to end of start (day).
18
+ def self.day_end start
19
+ finish = DateTime.new start.year, start.month, start.day, 23, 59
20
+ Timespan.new start, finish
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module Kalindar
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'ri_cal'
2
3
 
3
4
  describe Kalindar do
4
5
  it 'has a version number' do
@@ -24,52 +25,50 @@ describe EventCalendar do
24
25
  expect(cal.calendars.first.filename).to eql 'spec/testcal.ics'
25
26
  end
26
27
 
27
- describe "#find_events" do
28
- it 'finds events given date' do
29
- events = subject.find_events (Date.new(2014, 07, 27))
30
- event_names = events.map(&:summary)
31
- expect(event_names.include? "onehour").to eq true
32
- expect(event_names.include? "allday").to eq true
28
+
29
+ endjuly = Timespan.new(Date.new(2014, 07, 27), Date.new(2014, 07, 28)).freeze
30
+
31
+ latejuly = Date.new(2014, 07, 27).freeze
32
+
33
+ describe "#events_in" do
34
+ it 'finds recurring events' do
35
+ events = subject.events_in (Date.new(2014, 07, 28))
36
+ event_names = events.values.flatten.map(&:summary)
37
+ expect(event_names.include? "daily").to eq true
38
+ end
39
+ it 'finds multiday events that cover the given date' do
40
+ events = subject.events_in latejuly
41
+ expect(events.values.flatten.map(&:summary).include? "multidays").to eq true
33
42
  end
34
43
  it 'handles whole day endtime correctly (ends next day)' do
35
- events = subject.find_events (Date.new(2014, 07, 28))
36
- event_names = events.map(&:summary)
44
+ events = subject.events_in (Date.new(2014, 07, 28))
45
+ event_names = events.values.flatten.map(&:summary)
37
46
  expect(event_names.include? "allday").to eq false
38
47
  end
39
- it 'finds multiday events that cover the given date' do
40
- events = subject.find_events (Date.new(2014, 07, 27))
41
- expect(events.map(&:summary).include? "multidays").to eq true
48
+ it 'finds events given date (like find_events_simple)' do
49
+ events = subject.events_in latejuly
50
+ event_names = events.values.flatten.map(&:summary)
51
+ expect(event_names.include? "onehour").to eq true
52
+ expect(event_names.include? "allday").to eq true
42
53
  end
43
- it 'wraps events as Event delegates' do
44
- events = subject.find_events (Date.new(2014, 07, 27))
45
- events.each do |event|
46
- expect(event.is_a? Event).to eq true
47
- end
54
+ it 'finds normal recuring event.' do
55
+ events = subject.events_in (Date.new(2014, 07, 27))
56
+ expect(events.values.flatten.map(&:summary).include? "daily").to eq true
48
57
  end
49
- end
50
-
51
- it 'finds events that reocur' do
52
- events = subject.find_events (Date.new(2014, 07, 27))
53
- event_names = events.map(&:summary)
54
- expect(event_names.include? "daily").to eq true
55
- end
56
-
57
- describe "#events_in" do
58
+ # multiday events should come up multiple times!
58
59
  it 'accesses events between two dates' do
59
- events = subject.events_in(Date.new(2014, 07, 27), Date.new(2014, 07, 28))
60
- event_names = events.map(&:summary)
61
- expect(event_names).to eq ["allday", "onehour", "daily", "daily"]
60
+ events = subject.events_in endjuly
61
+ event_names = events.values.flatten.map(&:summary)
62
+ expect(event_names).to eq ["allday", "onehour", "multidays", "daily", "multidays", "daily"]
62
63
  end
63
64
  it '#events_in by day' do
64
- events = subject.events_in(Date.new(2014, 7, 27), Date.new(2014, 7, 28))
65
- event_names = events.map(&:summary)
66
- expect(event_names).to eq ["allday", "onehour", "daily", "allday", "daily"]
67
- expect(event_names.class).to eq({}.class)
65
+ events = subject.events_in endjuly
66
+ # And they come in a hash
67
+ expect(events.class).to eq({}.class)
68
68
  end
69
- # multiday events!
70
69
  it 'wraps in Event Delegate' do
71
- events = subject.events_in(Date.new(2014, 7, 27), Date.new(2014, 7, 28))
72
- expect(events.collect{|e| e.is_a? Event}.length).to eq events.length
70
+ events = subject.events_in endjuly
71
+ expect(events.values.flatten.collect{|e| e.is_a? Kalindar::Event}.length).to eq events.values.flatten.length
73
72
  end
74
73
  end
75
74
 
@@ -80,16 +79,17 @@ describe EventCalendar do
80
79
  end
81
80
  it 'wraps in Event Delegate' do
82
81
  event = subject.find_by_uid 'cb523dc2-eab8-49c9-a99f-ed69ac3b65d0'
83
- expect(event.is_a? Event).to eq true
82
+ expect(event.is_a? Kalindar::Event).to eq true
84
83
  end
85
84
  end
86
85
  end
87
86
 
88
87
  describe "Event" do
89
88
  subject(:allday_event) {}
89
+ # This tests the calendar, not the event class
90
90
  subject(:events) {
91
91
  cal = EventCalendar.new 'spec/testcal.ics'
92
- cal.events_in(Date.new(2014, 8, 27), Date.new(2014, 8, 28))
92
+ cal.events_in(Date.new(2014, 8, 27), Date.new(2014, 8, 28)).values.first
93
93
  }
94
94
  subject(:allday_event) {
95
95
  cal = EventCalendar.new 'spec/testcal.ics'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kalindar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Wolfsteller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-25 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ri_cal
@@ -155,6 +155,7 @@ files:
155
155
  - lib/kalindar/public/right-calendar.js
156
156
  - lib/kalindar/public/right-dialog.js
157
157
  - lib/kalindar/public/right.js
158
+ - lib/kalindar/timespan.rb
158
159
  - lib/kalindar/version.rb
159
160
  - lib/kalindar/views/.layout.haml.swp
160
161
  - lib/kalindar/views/edit_event.slim