Browse Source

Move calendar generation to Person, tzid

Maarten van den Berg 6 years ago
parent
commit
fa1600f24e
2 changed files with 89 additions and 78 deletions
  1. 1 78
      app/controllers/people_controller.rb
  2. 88 0
      app/models/person.rb

+ 1 - 78
app/controllers/people_controller.rb

@@ -91,87 +91,10 @@ class PeopleController < ApplicationController
91 91
 
92 92
   # GET /c/:calendar_token
93 93
   def calendar
94
-    cal = Icalendar::Calendar.new
95
-    cal.x_wr_calname = 'Aardbei'
96
-
97 94
     response.content_type = 'text/calendar'
98 95
 
99
-    selection = @person
100
-      .participants
101
-      .joins(:activity)
102
-      .where('"end" > ?', 3.months.ago)
103
-
104
-    if params[:skipcancel]
105
-      selection = selection
106
-        .where.not(attending: false)
107
-    end
108
-
109
-    selection.each do |p|
110
-      a = p.activity
111
-
112
-      description_items = []
113
-      # The description consists of the following parts:
114
-      #  - The Participant's response and notes (if set),
115
-      #  - The Activity's description (if not empty),
116
-      #  - The names of the organizers,
117
-      #  - Subgroup information, if applicable,
118
-      #  - The URL.
119
-
120
-      # Response
121
-      yourresponse = "#{I18n.t 'activities.participant.yourresponse'}: #{p.human_attending}"
122
-
123
-      if p.notes.present?
124
-        yourresponse << " (#{p.notes})"
125
-      end
126
-
127
-      description_items << yourresponse
128
-
129
-      # Description
130
-      description_items << a.description if a.description.present?
131
-
132
-      # Organizers
133
-      orgi = a.organizer_names
134
-      orgi_names = orgi.join ', '
135
-      orgi_line = case orgi.count
136
-                  when 0 then I18n.t 'activities.organizers.no_organizers'
137
-                  when 1 then "#{I18n.t 'activities.organizers.one'}: #{orgi_names}"
138
-                  else "#{I18n.t 'activities.organizers.other'}: #{orgi_names}"
139
-                  end
140
-
141
-      description_items << orgi_line
142
-
143
-      # Subgroups
144
-      if a.subgroups.any?
145
-        if p.subgroup
146
-          description_items << "#{I18n.t 'activities.participant.yoursubgroup'}: #{p.subgroup}"
147
-        end
148
-
149
-        subgroup_names = a.subgroups.map(&:name).join ', '
150
-        description_items << "#{I18n.t 'activerecord.models.subgroup.other'}: #{subgroup_names}"
151
-
152
-      end
153
-
154
-      # URL
155
-      a_url = group_activity_url a.group, a
156
-      description_items << a_url
157
-
158
-      cal.event do |e|
159
-        e.uid = a_url
160
-        e.dtstart = a.start
161
-        e.dtend = a.end
162
-
163
-        e.status = p.ical_attending
164
-
165
-        e.summary = a.name
166
-        e.location = a.location
167
-
168
-        e.description = description_items.join "\n"
169
-
170
-        e.url = a_url
171
-      end
172
-    end
96
+    cal = @person.calendar_feed
173 97
 
174
-    cal.publish
175 98
     render plain: cal.to_ical
176 99
   end
177 100
 

+ 88 - 0
app/models/person.rb

@@ -3,6 +3,7 @@
3 3
 # A Person may access the system by creating a User, and may have at most one
4 4
 # User.
5 5
 class Person < ApplicationRecord
6
+  include Rails.application.routes.url_helpers
6 7
   # @!attribute first_name
7 8
   #   @return [String]
8 9
   #     the person's first name. ('Vincent' in 'Vincent van Gogh'.)
@@ -102,6 +103,93 @@ class Person < ApplicationRecord
102 103
     person_calendar_url self.calendar_token
103 104
   end
104 105
 
106
+  # @return [Icalendar::Calendar]
107
+  #   this Person's upcoming activities feed.
108
+  def calendar_feed(skip_absent = false)
109
+    cal = Icalendar::Calendar.new
110
+    cal.x_wr_calname = 'Aardbei'
111
+
112
+    tzid = 1.seconds.since.time_zone.tzinfo.name
113
+
114
+    selection = self
115
+      .participants
116
+      .joins(:activity)
117
+      .where('"end" > ?', 3.months.ago)
118
+
119
+    if skip_absent
120
+      selection = selection
121
+        .where.not(attending: false)
122
+    end
123
+
124
+    selection.each do |p|
125
+      a = p.activity
126
+
127
+      description_items = []
128
+      # The description consists of the following parts:
129
+      #  - The Participant's response and notes (if set),
130
+      #  - The Activity's description (if not empty),
131
+      #  - The names of the organizers,
132
+      #  - Subgroup information, if applicable,
133
+      #  - The URL.
134
+
135
+      # Response
136
+      yourresponse = "#{I18n.t 'activities.participant.yourresponse'}: #{p.human_attending}"
137
+
138
+      if p.notes.present?
139
+        yourresponse << " (#{p.notes})"
140
+      end
141
+
142
+      description_items << yourresponse
143
+
144
+      # Description
145
+      description_items << a.description if a.description.present?
146
+
147
+      # Organizers
148
+      orgi = a.organizer_names
149
+      orgi_names = orgi.join ', '
150
+      orgi_line = case orgi.count
151
+                  when 0 then I18n.t 'activities.organizers.no_organizers'
152
+                  when 1 then "#{I18n.t 'activities.organizers.one'}: #{orgi_names}"
153
+                  else "#{I18n.t 'activities.organizers.other'}: #{orgi_names}"
154
+                  end
155
+
156
+      description_items << orgi_line
157
+
158
+      # Subgroups
159
+      if a.subgroups.any?
160
+        if p.subgroup
161
+          description_items << "#{I18n.t 'activities.participant.yoursubgroup'}: #{p.subgroup}"
162
+        end
163
+
164
+        subgroup_names = a.subgroups.map(&:name).join ', '
165
+        description_items << "#{I18n.t 'activerecord.models.subgroup.other'}: #{subgroup_names}"
166
+
167
+      end
168
+
169
+      # URL
170
+      a_url = group_activity_url a.group, a
171
+      description_items << a_url
172
+
173
+      cal.event do |e|
174
+        e.uid = a_url
175
+        e.dtstart = Icalendar::Values::DateTime.new a.start, tzid: tzid
176
+        e.dtend =   Icalendar::Values::DateTime.new a.end,   tzid: tzid
177
+
178
+        e.status = p.ical_attending
179
+
180
+        e.summary = a.name
181
+        e.location = a.location
182
+
183
+        e.description = description_items.join "\n"
184
+
185
+        e.url = a_url
186
+      end
187
+    end
188
+
189
+    cal.publish
190
+    cal
191
+  end
192
+
105 193
   private
106 194
   # Assert that the person's birth date, if any, lies in the past.
107 195
   def birth_date_cannot_be_in_future