kalindar 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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