forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathannouncements_api_controller.rb
More file actions
141 lines (127 loc) · 5.66 KB
/
Copy pathannouncements_api_controller.rb
File metadata and controls
141 lines (127 loc) · 5.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#
# Copyright (C) 2016 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# @API Announcements
#
# API for retrieving announcements. This API is Announcement-specific.
# See also the Discussion Topics API, which operates on Announcements also.
class AnnouncementsApiController < ApplicationController
include Api::V1::DiscussionTopics
before_action :parse_context_codes, :only => [:index]
before_action :get_dates, :only => [:index]
# @API List announcements
#
# Returns the paginated list of announcements for the given courses and date range. Note that
# a +context_code+ field is added to the responses so you can tell which course each announcement
# belongs to.
#
# @argument context_codes[] [Required]
# List of context_codes to retrieve announcements for (for example, +course_123+). Only courses
# are presently supported. The call will fail unless the caller has View Announcements permission
# in all listed courses.
# @argument start_date [Optional, Date]
# Only return announcements posted since the start_date (inclusive).
# Defaults to 14 days ago. The value should be formatted as: yyyy-mm-dd or ISO 8601 YYYY-MM-DDTHH:MM:SSZ.
# @argument end_date [Optional, Date]
# Only return announcements posted before the end_date (inclusive).
# Defaults to 28 days from start_date. The value should be formatted as: yyyy-mm-dd or ISO 8601 YYYY-MM-DDTHH:MM:SSZ.
# Announcements scheduled for future posting will only be returned to course administrators.
# @argument active_only [Optional, Boolean]
# Only return active announcements that have been published.
# Applies only to requesting users that have permission to view
# unpublished items.
# Defaults to false for users with access to view unpublished items,
# otherwise true and unmodifiable.
#
# @example_request
# curl https://<canvas>/api/v1/announcements?context_codes[]=course_1&context_codes[]=course_2 \
# -H 'Authorization: Bearer <token>'
#
# @example_response
# [{
# "id": 1,
# "title": "Hear ye",
# "message": "Henceforth, all assignments must be...",
# "posted_at": "2017-01-31T22:00:00Z",
# "delayed_post_at": null,
# "context_code": "course_2",
# ...
# }]
#
# @returns [DiscussionTopic]
def index
courses = api_find_all(Course, @course_ids)
return unless courses.all? { |course| authorized_action(course, @current_user, :read_announcements) }
scope = Announcement.where(:context_type => 'Course', :context_id => courses)
include_unpublished = courses.all? { |course| course.grants_right?(@current_user, :view_unpublished_items) }
scope = if include_unpublished && !value_to_boolean(params[:active_only])
scope.where.not(:workflow_state => 'deleted')
else
# workflow state should be 'post_delayed' if delayed_post_at is in the future, but check because other endpoints do
scope.where(:workflow_state => 'active').where('delayed_post_at IS NULL OR delayed_post_at<?', Time.now.utc)
end
@start_date ||= 14.days.ago.beginning_of_day
@end_date ||= @start_date + 28.days
scope = scope.where('COALESCE(delayed_post_at, posted_at) BETWEEN ? AND ?', @start_date, @end_date)
scope = scope.order('COALESCE(delayed_post_at, posted_at) DESC')
@topics = Api.paginate(scope, self, api_v1_announcements_url)
text_only = value_to_boolean(params[:text_only])
render :json => @topics.map { |topic|
discussion_topic_api_json(topic, topic.context, @current_user, session,
{ :user_can_moderate => false, :include_assignment => false,
:include_context_code => true, :text_only => text_only})
}
end
private
def parse_context_codes
context_codes = Array(params[:context_codes])
if context_codes.empty?
return render :json => { :message => 'Missing context_codes' }, :status => :bad_request
end
@course_ids = context_codes.inject([]) do |ids, context_code|
klass, id = ActiveRecord::Base.parse_asset_string(context_code)
unless klass == 'Course'
return render :json => { :message => 'Invalid context_codes; only `course` codes are supported' },
:status => :bad_request
end
ids << id
end
end
def get_dates
if params[:start_date].present?
if params[:start_date] =~ Api::DATE_REGEX
@start_date ||= Time.zone.parse(params[:start_date]).beginning_of_day
elsif params[:start_date] =~ Api::ISO8601_REGEX
@start_date ||= Time.zone.parse(params[:start_date])
else
render :json => { :message => 'Invalid start_date' }, :status => :bad_request
return false
end
end
if params[:end_date].present?
if params[:end_date] =~ Api::DATE_REGEX
@end_date ||= Time.zone.parse(params[:end_date]).end_of_day
elsif params[:end_date] =~ Api::ISO8601_REGEX
@end_date ||= Time.zone.parse(params[:end_date])
else
render :json => { :message => 'Invalid end_date' }, :status => :bad_request
return false
end
end
true
end
end