cal_months_rails3 1.0.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 +7 -0
- data/LICENSE +20 -0
- data/README.md +43 -0
- data/app/assets/javascripts/cal_months.js.coffee +19 -0
- data/app/assets/stylesheets/cal_months.css.sass +170 -0
- data/app/controllers/cal_months_controller.rb +10 -0
- data/app/helpers/cal_months_helper.rb +12 -0
- data/app/models/cal_event.rb +104 -0
- data/app/models/cal_month.rb +171 -0
- data/app/views/cal_months/_calendar.html.erb +6 -0
- data/app/views/cal_months/_month.html.erb +50 -0
- data/app/views/cal_months/_upcoming_events.html.erb +34 -0
- data/app/views/cal_months/show.js.erb +2 -0
- data/app/views/cal_months/show_current_event.js.erb +3 -0
- data/cal_months-1.0.0.gem +0 -0
- data/cal_months.gemspec +21 -0
- data/config/locales/cal_months_cs.yml +44 -0
- data/config/locales/cal_months_en.yml +44 -0
- data/db/migrate/create_cal_events.rb +13 -0
- data/db/migrate/create_cal_months.rb +11 -0
- data/lib/cal_months.rb +7 -0
- data/lib/generators/cal_months/install_generator.rb +50 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 28754ba3ac4c756df88b1f26b7162237e656df31
|
4
|
+
data.tar.gz: d19711faf88ad84aa2c59dcb46a14937f9ab6565
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3458225133f51c2fe63745e6577ff646bed3c40252080d64a1e8ef0a9fedcd4c4e22b17396a8edcf1bc9870b966517d9598e3c104edf92c224935cffe307f93
|
7
|
+
data.tar.gz: ccd96a735b0ad0250f8df4438659ed4655e70f6637876e8af89a526776691de7840beea873b231f98ff4ae2fd364068f1ce5c18c47b30d419a49984951689dc2
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 John Hager
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
*Rails 3*
|
2
|
+
# Cal Months
|
3
|
+
Allows for importing ical format calendars to the database with some default calendar views.
|
4
|
+
|
5
|
+
## Installing
|
6
|
+
|
7
|
+
Install the gem:
|
8
|
+
`gem cal_months`
|
9
|
+
|
10
|
+
Install the required files in your rails app:
|
11
|
+
`$ rails g cal_months:install`
|
12
|
+
|
13
|
+
Run migrations:
|
14
|
+
`$ rake db:migrate`
|
15
|
+
|
16
|
+
## Manually installing assets
|
17
|
+
|
18
|
+
Stylesheet:
|
19
|
+
`// require cal_month`
|
20
|
+
|
21
|
+
Javascript:
|
22
|
+
`//= require cal_month`
|
23
|
+
|
24
|
+
## Add Default Calendar Partial to a View
|
25
|
+
Add this to your view:
|
26
|
+
`render 'cal_months/calendar'`
|
27
|
+
|
28
|
+
Add this to your controller:
|
29
|
+
```
|
30
|
+
@cal_month = CalMonth.current_month
|
31
|
+
@current_event = CalMonth.upcoming_events.first
|
32
|
+
```
|
33
|
+
|
34
|
+
Note: `@cal_month` can be any `CalMonth`, and `@current_event` can be any item in the `CalMonth.upcoming_events` array.
|
35
|
+
|
36
|
+
## Importing icalendar
|
37
|
+
|
38
|
+
```
|
39
|
+
ical = File.open('path_to_ical.ics', 'r')
|
40
|
+
CalEvent.import_from_ical(ical)
|
41
|
+
```
|
42
|
+
|
43
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Place all the behaviors and hooks related to the matching controller here.
|
2
|
+
# All this logic will automatically be available in application.js.
|
3
|
+
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
4
|
+
|
5
|
+
|
6
|
+
add_on_calendar_date_on_hover_event = ->
|
7
|
+
$('.day.circled').hover(
|
8
|
+
(->
|
9
|
+
events = $(this).data('event-names')
|
10
|
+
html = "<ul><li>" + events.join('</li><li>') + "</li></ul>"
|
11
|
+
$('.month .more-info').html(html)
|
12
|
+
),
|
13
|
+
(-> $('.month .more-info').html('')))
|
14
|
+
|
15
|
+
$(document).on 'ready page:load', ->
|
16
|
+
add_on_calendar_date_on_hover_event()
|
17
|
+
|
18
|
+
$(document).ajaxComplete ->
|
19
|
+
add_on_calendar_date_on_hover_event()
|
@@ -0,0 +1,170 @@
|
|
1
|
+
|
2
|
+
// Calendar Styles
|
3
|
+
$calendar-primary: #006BB3
|
4
|
+
$calendar-primary-light: #3084c0
|
5
|
+
$calendar-secondary: #a8a8a8
|
6
|
+
$calendar-secondary-light: #f1f1f1
|
7
|
+
$calendar-third: green
|
8
|
+
$calendar-fourth: red
|
9
|
+
|
10
|
+
$calendar-width: 550px
|
11
|
+
|
12
|
+
// Calulated
|
13
|
+
$calendar-height: $calendar-width * 375 / 550
|
14
|
+
|
15
|
+
$day-size: $calendar-width / 2 / 10 * 8 / 7 - 4
|
16
|
+
$date-size: $calendar-height * 56 / 100
|
17
|
+
|
18
|
+
$big-font-size: $calendar-height * 70 / 375
|
19
|
+
$large-font-size: $calendar-height * 24 / 375
|
20
|
+
$medium-font-size: $calendar-height * 20 / 375
|
21
|
+
$normal-font-size: $calendar-height * 16 / 375
|
22
|
+
$small-font-size: $calendar-height * 12 / 375
|
23
|
+
|
24
|
+
$large-vertical-padding: $calendar-height * 45 / 375
|
25
|
+
$medium-vertical-padding: $calendar-height * 15 / 375
|
26
|
+
$small-vertical-padding: $calendar-height * 5 / 375
|
27
|
+
|
28
|
+
$small-horizontal-padding: $calendar-width * 10 / 550
|
29
|
+
|
30
|
+
.calendar-container
|
31
|
+
div
|
32
|
+
box-sizing: border-box
|
33
|
+
.calendar
|
34
|
+
width: $calendar-width
|
35
|
+
height: $calendar-height
|
36
|
+
margin-top: 20px
|
37
|
+
display: inline-block
|
38
|
+
.upcoming-events
|
39
|
+
width: $calendar-width / 2
|
40
|
+
height: $calendar-height
|
41
|
+
background: $calendar-primary
|
42
|
+
padding: $small-vertical-padding $small-horizontal-padding $small-vertical-padding $small-horizontal-padding
|
43
|
+
display: inline-block
|
44
|
+
position: relative
|
45
|
+
color: white
|
46
|
+
.date
|
47
|
+
height: $date-size
|
48
|
+
font-size: $big-font-size
|
49
|
+
text-align: center
|
50
|
+
.block-left, .block-right
|
51
|
+
height: $date-size
|
52
|
+
.event-info
|
53
|
+
height: $calendar-height * 115 / 375
|
54
|
+
font-size: $normal-font-size
|
55
|
+
padding: $small-horizontal-padding $medium-vertical-padding 0 $medium-vertical-padding
|
56
|
+
text-align: center
|
57
|
+
.name
|
58
|
+
font-weight: bold
|
59
|
+
.more-info
|
60
|
+
position: relative
|
61
|
+
.time
|
62
|
+
display: none
|
63
|
+
&:hover
|
64
|
+
cursor: pointer
|
65
|
+
.time
|
66
|
+
font-size: $small-font-size
|
67
|
+
display: block
|
68
|
+
position: relative
|
69
|
+
font-weight: bold
|
70
|
+
.month
|
71
|
+
height: $calendar-height
|
72
|
+
width: $calendar-width / 2
|
73
|
+
border-top: 1px solid $calendar-secondary-light
|
74
|
+
border-bottom: 1px solid $calendar-secondary-light
|
75
|
+
border-right: 1px solid $calendar-secondary-light
|
76
|
+
padding: $small-vertical-padding $small-horizontal-padding $small-vertical-padding $small-horizontal-padding
|
77
|
+
position: relative
|
78
|
+
display: inline-block
|
79
|
+
background: white
|
80
|
+
a.navigation-left, a.navigation-right, .more-info a
|
81
|
+
color: $calendar-primary
|
82
|
+
&:hover, &:visited, &:focus
|
83
|
+
color: $calendar-primary
|
84
|
+
.calendar-grid
|
85
|
+
.block-left, .block-right
|
86
|
+
width: $calendar-width / 2 / 10
|
87
|
+
.grid
|
88
|
+
border-top: 1px solid $calendar-secondary
|
89
|
+
width: $calendar-width / 2 / 10 * 8
|
90
|
+
padding-top: $medium-vertical-padding
|
91
|
+
border-bottom-color: transparent
|
92
|
+
text-align: justify
|
93
|
+
.cal-head-row
|
94
|
+
height: $day-size
|
95
|
+
.day
|
96
|
+
width: $day-size
|
97
|
+
height: $day-size
|
98
|
+
cursor: auto
|
99
|
+
.weekend
|
100
|
+
color: $calendar-primary
|
101
|
+
.cal-row
|
102
|
+
position: relative
|
103
|
+
margin-top: $small-vertical-padding
|
104
|
+
height: $day-size
|
105
|
+
.day
|
106
|
+
width: $day-size
|
107
|
+
height: $day-size
|
108
|
+
font-size: $normal-font-size
|
109
|
+
cursor: pointer
|
110
|
+
display: inline-block
|
111
|
+
border-radius: 100%
|
112
|
+
text-align: center
|
113
|
+
&.null
|
114
|
+
border: 1px solid transparent
|
115
|
+
color: transparent
|
116
|
+
&.past
|
117
|
+
color: $calendar-secondary
|
118
|
+
&.circled
|
119
|
+
border: 1px solid $calendar-secondary
|
120
|
+
&.circled
|
121
|
+
border: 1px solid $calendar-primary
|
122
|
+
.more-info
|
123
|
+
width: $calendar-width / 2
|
124
|
+
font-size: $small-font-size
|
125
|
+
padding: $small-horizontal-padding $medium-vertical-padding 0 $medium-vertical-padding
|
126
|
+
text-align: left
|
127
|
+
font-weight: bold
|
128
|
+
|
129
|
+
.calendar-container
|
130
|
+
.navigation
|
131
|
+
padding-top: $calendar-height * 4 / 30 / 10
|
132
|
+
height: $calendar-height * 4 / 30
|
133
|
+
font-size: $medium-font-size
|
134
|
+
text-align: center
|
135
|
+
.text
|
136
|
+
top: $calendar-height * 4 / 30 / 10 / 5 * 8
|
137
|
+
position: relative
|
138
|
+
|
139
|
+
.block-left, .block-right
|
140
|
+
width: $calendar-width / 2 * 0.15
|
141
|
+
display: inline-block
|
142
|
+
position: absolute
|
143
|
+
|
144
|
+
.navigation-right, .navigation-left
|
145
|
+
font-size: $large-font-size
|
146
|
+
font-weight: bold
|
147
|
+
|
148
|
+
.block-left
|
149
|
+
left: 0
|
150
|
+
.block-right
|
151
|
+
right: 0
|
152
|
+
|
153
|
+
a.navigation-left, a.navigation-right, .more-info a
|
154
|
+
color: white
|
155
|
+
&:hover, &:visited, &:focus
|
156
|
+
text-decoration: none
|
157
|
+
color: white
|
158
|
+
|
159
|
+
|
160
|
+
.date .number, .calendar-grid .grid
|
161
|
+
height: $date-size
|
162
|
+
width: $calendar-width / 2 / 10 * 7
|
163
|
+
padding-top: $large-vertical-padding
|
164
|
+
position: relative
|
165
|
+
display: inline-block
|
166
|
+
border-bottom: 1px solid $calendar-primary-light
|
167
|
+
border-top: 1px solid $calendar-primary-light
|
168
|
+
// END Calendar Styles
|
169
|
+
|
170
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module CalMonthsHelper
|
2
|
+
def pretty_from_to(event)
|
3
|
+
dtstart, dtend = event[:start_datetime], event[:end_datetime]
|
4
|
+
if dtstart.to_date == dtend.to_date
|
5
|
+
"#{dtstart.strftime('%A, %d %b, %H:%M')} - " +
|
6
|
+
"#{dtend.strftime('%H:%M')}"
|
7
|
+
else
|
8
|
+
[dtstart, dtend].map { |dt| dt.strftime('%A, %d %b, %H:%M') }
|
9
|
+
.join(' - ')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'icalendar'
|
2
|
+
class CalEvent < ActiveRecord::Base
|
3
|
+
|
4
|
+
attr_accessible :name, :description, :rdate, :system_uid, :system_updated_at
|
5
|
+
|
6
|
+
validates_presence_of :system_uid, :system_updated_at
|
7
|
+
|
8
|
+
scope :for_month, ->(year, month) {
|
9
|
+
ids = all.map { |event|
|
10
|
+
event.id if event.months_affected.include?([year,month])
|
11
|
+
}.compact
|
12
|
+
where(id: ids)
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.months_affected
|
16
|
+
all.flat_map(&:months_affected).uniq.sort
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create_or_update(attributes = {})
|
20
|
+
new_event = CalEvent.new(attributes)
|
21
|
+
raise ActiveRecord::RecordInvalid unless new_event.valid?
|
22
|
+
|
23
|
+
found = CalEvent.find_by_system_uid(new_event.system_uid)
|
24
|
+
|
25
|
+
if found
|
26
|
+
if found.system_updated_at < new_event.system_updated_at
|
27
|
+
found.update_attributes(
|
28
|
+
name: new_event.name,
|
29
|
+
description: new_event.description,
|
30
|
+
system_updated_at: new_event.system_updated_at
|
31
|
+
)
|
32
|
+
end
|
33
|
+
found
|
34
|
+
else
|
35
|
+
new_event.save
|
36
|
+
new_event
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.import_from_ical(ical)
|
41
|
+
ids = []
|
42
|
+
cals = Icalendar.parse(ical)
|
43
|
+
cals.each do |cal|
|
44
|
+
cal.events.each do |event|
|
45
|
+
db_event = CalEvent.create_or_update(
|
46
|
+
name: event.summary.to_s,
|
47
|
+
description: event.description.to_s,
|
48
|
+
system_uid: event.uid.to_s,
|
49
|
+
system_updated_at: event.last_modified.to_datetime,
|
50
|
+
)
|
51
|
+
if event.rdate.empty?
|
52
|
+
db_event.rdate = [
|
53
|
+
[event.dtstart.to_datetime, event.dtend.to_datetime]
|
54
|
+
].to_json
|
55
|
+
else
|
56
|
+
db_event.rdate = event.rdate[0].to_json
|
57
|
+
end
|
58
|
+
db_event.save
|
59
|
+
ids << db_event.id
|
60
|
+
end
|
61
|
+
end
|
62
|
+
events = CalEvent.where(id: ids)
|
63
|
+
events.months_affected.each do |year, month|
|
64
|
+
data = events.for_month(year, month).to_event_data(year, month)
|
65
|
+
CalMonth.create_or_update(
|
66
|
+
year: year, month: month, event_data: data
|
67
|
+
)
|
68
|
+
end
|
69
|
+
events
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.to_event_data(year, month)
|
73
|
+
all.each_with_object(Hash.new {|h,k| h[k] = []}) { |event, data|
|
74
|
+
event.to_event_data[[year, month]].each do |day, event_data|
|
75
|
+
data[day] << event_data
|
76
|
+
end
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_event_data
|
81
|
+
data = Hash.new { |h,k| h[k] = {} }
|
82
|
+
datetimes.each {|start_datetime, end_datetime|
|
83
|
+
(start_datetime..end_datetime).each do |day|
|
84
|
+
data[[day.year, day.month]][day.day] = {
|
85
|
+
id: id,
|
86
|
+
name: name,
|
87
|
+
start_datetime: start_datetime,
|
88
|
+
end_datetime: end_datetime
|
89
|
+
}
|
90
|
+
end
|
91
|
+
}
|
92
|
+
data
|
93
|
+
end
|
94
|
+
|
95
|
+
# array of array [[start_datetime, end_datetime],...]
|
96
|
+
def datetimes
|
97
|
+
data = JSON.parse(rdate)
|
98
|
+
data.map { |pair| pair.map { |str| DateTime.parse(str) } }
|
99
|
+
end
|
100
|
+
|
101
|
+
def months_affected
|
102
|
+
datetimes.flatten.map { |date| [date.year, date.month] }.uniq.sort
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
class CalMonth < ActiveRecord::Base
|
2
|
+
|
3
|
+
attr_accessible :event_data, :month, :year
|
4
|
+
|
5
|
+
validates_presence_of :month, :year
|
6
|
+
validate :unique_month
|
7
|
+
|
8
|
+
def self.find_month(year, month)
|
9
|
+
CalMonth.where(year: year, month: month).limit(1).first
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.current_month
|
13
|
+
date = Date.today
|
14
|
+
fetch_month(date.year, date.month)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fetch_month(year, month)
|
18
|
+
if found = find_month(year, month)
|
19
|
+
found
|
20
|
+
else
|
21
|
+
CalMonth.new(year: year, month: month)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create_or_update(attributes = {})
|
26
|
+
month = find_month(attributes[:year], attributes[:month]) ||
|
27
|
+
CalMonth.new(year: attributes[:year], month: attributes[:month])
|
28
|
+
|
29
|
+
month.update_event_data(attributes[:event_data])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns event data: array of hash, sorted by start datetime
|
33
|
+
# e.g. [{"id" => 1, "name" => "Next Event", "start_datetime" =>
|
34
|
+
def self.upcoming_events(date = nil)
|
35
|
+
date ||= Date.today
|
36
|
+
months = where('year >= ? AND month >= ?', date.year, date.month)
|
37
|
+
.order(:year).order(:month).limit(2)
|
38
|
+
|
39
|
+
unless months.empty?
|
40
|
+
events = months.first.events_after_day(date.day)
|
41
|
+
if events.empty?
|
42
|
+
months.last.events_after_day
|
43
|
+
else
|
44
|
+
events
|
45
|
+
end
|
46
|
+
else
|
47
|
+
[{
|
48
|
+
start_datetime: Date.today.to_datetime,
|
49
|
+
end_datetime: Date.today.to_datetime,
|
50
|
+
name: ''
|
51
|
+
}]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def events_after_day(day = 1)
|
56
|
+
eventful_day = date_events[(day-1)..-1].find { |day, data|
|
57
|
+
!data.empty? &&
|
58
|
+
data.any? { |event|
|
59
|
+
event[:end_datetime] > Time.zone.now
|
60
|
+
}
|
61
|
+
}
|
62
|
+
return [] unless eventful_day
|
63
|
+
|
64
|
+
events = eventful_day.last.sort_by {|event| event[:start_datetime]}
|
65
|
+
events.delete_if { |event| event[:end_datetime] < Time.zone.now }
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def to_a
|
70
|
+
[year, month]
|
71
|
+
end
|
72
|
+
|
73
|
+
def next_month_array
|
74
|
+
n_year = year
|
75
|
+
n_month = month + 1
|
76
|
+
if n_month == 13
|
77
|
+
n_year += 1
|
78
|
+
n_month = 1
|
79
|
+
end
|
80
|
+
[n_year, n_month]
|
81
|
+
end
|
82
|
+
|
83
|
+
def prev_month_array
|
84
|
+
n_year = year
|
85
|
+
n_month = month - 1
|
86
|
+
if n_month == 0
|
87
|
+
n_year -= 1
|
88
|
+
n_month = 12
|
89
|
+
end
|
90
|
+
[n_year, n_month]
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_date
|
94
|
+
Date.new(year, month)
|
95
|
+
end
|
96
|
+
|
97
|
+
def days
|
98
|
+
(1..to_date.end_of_month.day).to_a
|
99
|
+
end
|
100
|
+
|
101
|
+
def events_for_day?(day)
|
102
|
+
!events_for_day(day).empty?
|
103
|
+
end
|
104
|
+
|
105
|
+
def events_for_day(day)
|
106
|
+
date_events_hash[day.to_s]
|
107
|
+
end
|
108
|
+
|
109
|
+
def date_events
|
110
|
+
date_events_hash.sort_by { |date,_| date.to_i }
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_event_data(new_data)
|
114
|
+
new_data.stringify_keys
|
115
|
+
old_data = JSON.parse(event_data || '{}')
|
116
|
+
data = merge_default_data(old_data).merge(new_data)
|
117
|
+
|
118
|
+
update_attribute(:event_data, data.to_json)
|
119
|
+
end
|
120
|
+
|
121
|
+
def each_week
|
122
|
+
date = to_date
|
123
|
+
data = date_events
|
124
|
+
day_of_week_offset = date.wday - 1
|
125
|
+
day_of_week_offset.times { data.unshift([nil, []]) }
|
126
|
+
|
127
|
+
if block_given?
|
128
|
+
data.each_slice(7) { |week| yield(week) }
|
129
|
+
else
|
130
|
+
data.each_slice(7)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
def merge_default_data(to_merge)
|
136
|
+
blank_days_hash.merge(to_merge)
|
137
|
+
end
|
138
|
+
|
139
|
+
def date_events_hash
|
140
|
+
@date_events_hash ||= merge_default_data(parsed_event_data)
|
141
|
+
end
|
142
|
+
|
143
|
+
def parsed_event_data
|
144
|
+
data = JSON.parse(event_data || '{}')
|
145
|
+
data = create_hash_with_indifferent_access(data)
|
146
|
+
data.each do |day, value|
|
147
|
+
value.each_with_index do |event, index|
|
148
|
+
[:start_datetime, :end_datetime].each do |key|
|
149
|
+
data[day][index][key] = DateTime.parse(data[day][index][key])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def create_hash_with_indifferent_access(hash)
|
156
|
+
ActiveSupport::HashWithIndifferentAccess.new(hash)
|
157
|
+
end
|
158
|
+
|
159
|
+
def blank_days_hash
|
160
|
+
days.each_with_object({}) { |day, hash| hash[day] = [] }
|
161
|
+
.stringify_keys!
|
162
|
+
end
|
163
|
+
|
164
|
+
def unique_month
|
165
|
+
found = CalMonth.where(year: year, month: month)
|
166
|
+
.where('NOT(id = ?)', id)
|
167
|
+
if found.first
|
168
|
+
errors[:base] << "Unique month required. If you are reading this, there is a bug in the creation or updating of CalMonth models."
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<div class="pull-left month">
|
2
|
+
<div class="navigation">
|
3
|
+
<div class="block-left">
|
4
|
+
<%= link_to cal_month_path(*@cal_month.prev_month_array, format: :js), class: 'navigation-left', remote: true do %>
|
5
|
+
<span class="glyphicon glyphicon-chevron-left"></span>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
8
|
+
<% year, month = @cal_month.to_a %>
|
9
|
+
<span class="text"><%= "#{t(".month.#{month}")} '#{year.to_s[-2..-1]}" %></span>
|
10
|
+
<div class="block-right">
|
11
|
+
<%= link_to cal_month_path(*@cal_month.next_month_array, format: :js), class: 'navigation-right', remote: true do %>
|
12
|
+
<span class="glyphicon glyphicon-chevron-right"></span>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<div class="calendar-grid">
|
17
|
+
<div class="block-left"></div>
|
18
|
+
<div class="grid">
|
19
|
+
<div class="cal-head-row">
|
20
|
+
<div class="day"><%=t('.day.short.1') %></div>
|
21
|
+
<div class="day"><%=t('.day.short.2') %></div>
|
22
|
+
<div class="day"><%=t('.day.short.3') %></div>
|
23
|
+
<div class="day"><%=t('.day.short.4') %></div>
|
24
|
+
<div class="day"><%=t('.day.short.5') %></div>
|
25
|
+
<div class="day weekend"><%=t('.day.short.6') %></div>
|
26
|
+
<div class="day weekend"><%=t('.day.short.7') %></div>
|
27
|
+
</div>
|
28
|
+
<% @cal_month.each_week do |week| %>
|
29
|
+
<div class="cal-row">
|
30
|
+
<% week.each do |day, events| %>
|
31
|
+
<% if @cal_month.to_date == Date.today.beginning_of_month %>
|
32
|
+
<% past = Date.today.day > day.to_i %>
|
33
|
+
<% else %>
|
34
|
+
<% past = Date.today > @cal_month.to_date %>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<% event_names = events.map {|event| truncate(event[:name], length: 34, omission: '...')} %>
|
38
|
+
<% if event_names.length > 5 %>
|
39
|
+
<% event_names = event_names[0..3] %>
|
40
|
+
<% event_names.push('<div class="text-center">...</div>') %>
|
41
|
+
<% end %>
|
42
|
+
<%= content_tag :div, day || '0', class: "day #{"null" unless day} #{"circled" unless events.empty?} #{"past" if past && day}", data: { event_names: event_names } %>
|
43
|
+
<% end %>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
<div class="block-right"></div>
|
48
|
+
</div>
|
49
|
+
<div class="more-info"></div>
|
50
|
+
</div>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<div class="pull-left upcoming-events">
|
2
|
+
<div class="navigation">
|
3
|
+
<div class="block-left">
|
4
|
+
<% unless CalMonth.upcoming_events.first == @current_event %>
|
5
|
+
<%= link_to current_event_path(CalMonth.upcoming_events.index(@current_event) - 1, format: :js), class: 'navigation-left', remote: true do %>
|
6
|
+
<span class="glyphicon glyphicon-chevron-left"></span>
|
7
|
+
<% end %>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<span class="text"><%= t(".day.#{@current_event[:start_datetime].wday}") %></span>
|
11
|
+
<div class="block-right">
|
12
|
+
<% unless CalMonth.upcoming_events.last == @current_event %>
|
13
|
+
<%= link_to current_event_path(CalMonth.upcoming_events.index(@current_event) + 1, format: :js), class: 'navigation-right', remote: true do %>
|
14
|
+
<span class="glyphicon glyphicon-chevron-right"></span>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
<div class="date">
|
20
|
+
<div class="block-left"></div>
|
21
|
+
<div class="number">
|
22
|
+
<span class="text"><%= @current_event[:start_datetime].day %></span>
|
23
|
+
</div>
|
24
|
+
<div class="block-right"></div>
|
25
|
+
</div>
|
26
|
+
<div class="event-info">
|
27
|
+
<div class="name"><%= truncate(@current_event[:name], length: 45, omission: '...') %></div>
|
28
|
+
<div class="more-info">
|
29
|
+
<span><%= ". . ." %></span>
|
30
|
+
<div class="time"><%= pretty_from_to(@current_event) %></div>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
Binary file
|
data/cal_months.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
current_dir = File.expand_path('..', __FILE__)
|
2
|
+
#extensions = %w{ rb yml haml erb slim html js json jbuilder }
|
3
|
+
#files = Dir.glob(current_dir + "/**/*.{#{extensions.join(',')}}")
|
4
|
+
files = Dir.glob(current_dir + '/**/*')
|
5
|
+
files.collect! {|file| file.sub(current_dir + '/', '')}
|
6
|
+
files.push('LICENSE')
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = 'cal_months_rails3'
|
10
|
+
s.version = '1.0.1'
|
11
|
+
s.date = "#{Time.now.strftime("%Y-%m-%d")}"
|
12
|
+
s.homepage = 'https://github.com/jphager2/cal_months'
|
13
|
+
s.summary = 'icalendar integration'
|
14
|
+
s.description = 'A nice extension for quickly incorporating icalendar imports with default views (Rails 4)'
|
15
|
+
s.authors = ['jphager2']
|
16
|
+
s.email = 'jphager2@gmail.com'
|
17
|
+
s.files = files
|
18
|
+
s.license = 'MIT'
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'icalendar', '~> 2.2'
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
cs:
|
2
|
+
cal_months:
|
3
|
+
calendar:
|
4
|
+
month:
|
5
|
+
month:
|
6
|
+
"1": Leden
|
7
|
+
"2": Únor
|
8
|
+
"3": Březen
|
9
|
+
"4": Duben
|
10
|
+
"5": Květen
|
11
|
+
"6": Červen
|
12
|
+
"7": Červenec
|
13
|
+
"8": Srpen
|
14
|
+
"9": Září
|
15
|
+
"10": Říjen
|
16
|
+
"11": Listopad
|
17
|
+
"12": Prosinec
|
18
|
+
day:
|
19
|
+
short:
|
20
|
+
"1": P
|
21
|
+
"2": Ú
|
22
|
+
"3": S
|
23
|
+
"4": Č
|
24
|
+
"5": P
|
25
|
+
"6": S
|
26
|
+
"7": N
|
27
|
+
long:
|
28
|
+
"1": Pondělí
|
29
|
+
"2": Úterý
|
30
|
+
"3": Středa
|
31
|
+
"4": Čtvrtek
|
32
|
+
"5": Pátek
|
33
|
+
"6": Sobota
|
34
|
+
"7": Neděle
|
35
|
+
upcoming_events:
|
36
|
+
day:
|
37
|
+
"1": Pondělí
|
38
|
+
"2": Úterý
|
39
|
+
"3": Středa
|
40
|
+
"4": Čtvrtek
|
41
|
+
"5": Pátek
|
42
|
+
"6": Sobota
|
43
|
+
"7": Neděle
|
44
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
en:
|
2
|
+
cal_months:
|
3
|
+
calendar:
|
4
|
+
month:
|
5
|
+
month:
|
6
|
+
"1": January
|
7
|
+
"2": February
|
8
|
+
"3": March
|
9
|
+
"4": April
|
10
|
+
"5": May
|
11
|
+
"6": June
|
12
|
+
"7": July
|
13
|
+
"8": August
|
14
|
+
"9": September
|
15
|
+
"10": October
|
16
|
+
"11": November
|
17
|
+
"12": December
|
18
|
+
day:
|
19
|
+
short:
|
20
|
+
"1": M
|
21
|
+
"2": T
|
22
|
+
"3": W
|
23
|
+
"4": T
|
24
|
+
"5": F
|
25
|
+
"6": S
|
26
|
+
"7": S
|
27
|
+
long:
|
28
|
+
"1": Monday
|
29
|
+
"2": Tuesday
|
30
|
+
"3": Wednesday
|
31
|
+
"4": Thursday
|
32
|
+
"5": Friday
|
33
|
+
"6": Saturday
|
34
|
+
"7": Sunday
|
35
|
+
upcoming_events:
|
36
|
+
day:
|
37
|
+
"1": Monday
|
38
|
+
"2": Tuesday
|
39
|
+
"3": Wednesday
|
40
|
+
"4": Thursday
|
41
|
+
"5": Friday
|
42
|
+
"6": Saturday
|
43
|
+
"7": Sunday
|
44
|
+
|
data/lib/cal_months.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
gem_app_path = File.expand_path('../..', __FILE__)
|
2
|
+
autoload :CalMonthsController, "#{gem_app_path}/app/controllers/cal_months_controller"
|
3
|
+
autoload :CalMonthsHelper, "#{gem_app_path}/app/helpers/cal_months_helper"
|
4
|
+
autoload :CalEvent, "#{gem_app_path}/app/models/cal_event"
|
5
|
+
autoload :CalMonth, "#{gem_app_path}/app/models/cal_month"
|
6
|
+
|
7
|
+
autoload :InstallGenerator, "#{gem_app_path}lib/generators/cal_months/install_generator"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module CalMonths
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../../templates", __FILE__)
|
7
|
+
|
8
|
+
def copy_locale
|
9
|
+
copy_file '../../../config/locales/cal_months_en.yml', 'config/locales/cal_months_en.yml'
|
10
|
+
copy_file '../../../config/locales/cal_months_cs.yml', 'config/locales/cal_months_cs.yml'
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_stylesheets
|
14
|
+
copy_file '../../../app/assets/javascripts/cal_months.js.coffee', 'app/assets/javascripts/cal_months.js.coffee'
|
15
|
+
copy_file '../../../app/assets/stylesheets/cal_months.css.sass', 'app/assets/stylesheets/cal_months.css.sass'
|
16
|
+
insert_into_file "app/assets/stylesheets/application#{detect_css_format[0]}", "\n#{detect_css_format[1]} require cal_months\n", :after => "require_self"
|
17
|
+
end
|
18
|
+
|
19
|
+
def detect_css_format
|
20
|
+
return ['.css', ' *='] if File.exist?('app/assets/stylesheets/application.css')
|
21
|
+
return ['.css.sass', ' //='] if File.exist?('app/assets/stylesheets/application.css.sass')
|
22
|
+
return ['.sass', ' //='] if File.exist?('app/assets/stylesheets/application.sass')
|
23
|
+
return ['.css.scss', ' //='] if File.exist?('app/assets/stylesheets/application.css.scss')
|
24
|
+
return ['.scss', ' //='] if File.exist?('app/assets/stylesheets/application.scss')
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_helper
|
28
|
+
insert_into_file "app/helpers/application_helper.rb", "\n include CalMonthsHelper\n", after: "module ApplicationHelper"
|
29
|
+
end
|
30
|
+
|
31
|
+
def copy_views
|
32
|
+
copy_file '../../../app/views/cal_months/_calendar.html.erb', 'app/views/cal_months/_calendar.html.erb'
|
33
|
+
copy_file '../../../app/views/cal_months/_month.html.erb', 'app/views/cal_months/_month.html.erb'
|
34
|
+
copy_file '../../../app/views/cal_months/_upcoming_events.html.erb', 'app/views/cal_months/_upcoming_events.html.erb'
|
35
|
+
copy_file '../../../app/views/cal_months/show.js.erb', 'app/views/cal_months/show.js.erb'
|
36
|
+
copy_file '../../../app/views/cal_months/show_current_event.js.erb', 'app/views/cal_months/show_current_event.js.erb'
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_routes
|
40
|
+
route "get '/cal_months/calendar/:year-:month', to: 'cal_months#show', as: :cal_month"
|
41
|
+
route "get '/cal_months/current-events/:id', to: 'cal_months#show_current_event', as: :current_event"
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_migrations
|
45
|
+
copy_file '../../../db/migrate/create_cal_events.rb', "db/migrate/#{Time.now.to_i}_create_cal_events.rb"
|
46
|
+
copy_file '../../../db/migrate/create_cal_months.rb', "db/migrate/#{Time.now.to_i + 1}_create_cal_months.rb"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cal_months_rails3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jphager2
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: icalendar
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
description: A nice extension for quickly incorporating icalendar imports with default
|
28
|
+
views (Rails 4)
|
29
|
+
email: jphager2@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE
|
35
|
+
- README.md
|
36
|
+
- app/assets/javascripts/cal_months.js.coffee
|
37
|
+
- app/assets/stylesheets/cal_months.css.sass
|
38
|
+
- app/controllers/cal_months_controller.rb
|
39
|
+
- app/helpers/cal_months_helper.rb
|
40
|
+
- app/models/cal_event.rb
|
41
|
+
- app/models/cal_month.rb
|
42
|
+
- app/views/cal_months/_calendar.html.erb
|
43
|
+
- app/views/cal_months/_month.html.erb
|
44
|
+
- app/views/cal_months/_upcoming_events.html.erb
|
45
|
+
- app/views/cal_months/show.js.erb
|
46
|
+
- app/views/cal_months/show_current_event.js.erb
|
47
|
+
- cal_months-1.0.0.gem
|
48
|
+
- cal_months.gemspec
|
49
|
+
- config/locales/cal_months_cs.yml
|
50
|
+
- config/locales/cal_months_en.yml
|
51
|
+
- db/migrate/create_cal_events.rb
|
52
|
+
- db/migrate/create_cal_months.rb
|
53
|
+
- lib/cal_months.rb
|
54
|
+
- lib/generators/cal_months/install_generator.rb
|
55
|
+
homepage: https://github.com/jphager2/cal_months
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.2.2
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: icalendar integration
|
79
|
+
test_files: []
|