-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathpoints_controller.rb
More file actions
143 lines (123 loc) · 4.93 KB
/
points_controller.rb
File metadata and controls
143 lines (123 loc) · 4.93 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
142
143
require 'natsort'
# Shows the points summary table and exercise group-specific tables.
class PointsController < ApplicationController
include PointsHelper
before_action :set_organization
def index
@course = Course.find(params[:course_id])
authorize! :see_points, @course
add_course_breadcrumb
add_breadcrumb 'Points'
if can?(:teach, @course)
@user_fields = UserField.all.select do |field|
field.show_in_participant_list?
end
end
only_for_user = User.find_by(login: params[:username])
if only_for_user
exercises = @course.exercises.enabled.where(exercises: { hidden: false, hide_submission_results: false })
sheets = @course.gdocs_sheets(exercises).natsort
@summary = summary_hash(@course, exercises, sheets, only_for_user)
sort_summary(@summary, params[:sort_by]) if params[:sort_by]
@summary
else
@summary = Rails.cache.fetch("points_#{@course.id}_admin_#{current_user.administrator?}/", expires_in: 1.minute) do
exercises = @course.exercises.enabled.where(exercises: { hidden: false })
exercises = exercises.where(hide_submission_results: false) unless current_user.administrator?
sheets = @course.gdocs_sheets(exercises).natsort
@summary = summary_hash(@course, exercises, sheets)
@summary
end
sort_summary(@summary, params[:sort_by]) if params[:sort_by]
end
respond_to do |format|
format.html
format.csv do
render_csv(filename: "#{@course.name}_points.csv")
end
format.json { render json: @summary }
end
end
def refresh_gdocs
authorize! :refresh, @course
@sheetname = params[:id]
@course = Course.find(params[:course_id])
@notifications = @course.refresh_gdocs_worksheet @sheetname
end
def show
@sheetname = params[:id]
@course = Course.find(params[:course_id])
authorize! :see_points, @course
show_timestamps = !!params[:timestamps]
if can?(:teach, @course)
@user_fields = UserField.all.select do |field|
field.show_in_participant_list?
end
end
add_course_breadcrumb
add_breadcrumb 'Points', organization_course_points_path(@organization, @course)
add_breadcrumb @sheetname
@exercises = Exercise.course_gdocs_sheet_exercises(@course, @sheetname, current_user.administrator?).includes(:available_points).order!(:name)
@users_to_points = AwardedPoint.per_user_in_course_with_sheet(@course, @sheetname, show_timestamps: show_timestamps, hidden: current_user.administrator?)
@users = @course.users.includes(:user_field_values)
if params[:sort_by] == 'points'
@users = @users.sort_by do |u|
[-@users_to_points[u.login].size, u.login.downcase]
end
else
@users.order!
end
respond_to do |format|
format.html
format.csv do
render_csv(filename: "#{@course.name}_#{@sheetname}_points.csv")
end
format.json do
output = {
api_version: ApiVersion::API_VERSION,
users_to_points: @users_to_points
}
render json: output
end
end
end
private
def summary_hash(course, visible_exercises, sheets, only_for_user = nil)
per_user_and_sheet = AwardedPoint.count_per_user_in_course_with_sheet(course, sheets, only_for_user, current_user.administrator?)
user_totals = {}
for username, per_sheet in per_user_and_sheet
user_totals[username] ||= 0
user_totals[username] += per_sheet.values.reduce(0, &:+)
end
include_admins = current_user.administrator?
users = User.select('login, users.id, administrator').where(login: per_user_and_sheet.keys.sort_by(&:downcase)).includes(:organizations).includes(:user_field_values).order('login ASC')
users = users.where(administrator: false) unless include_admins
total_awarded = AwardedPoint.course_sheet_points(course, sheets, include_admins)
total_available = AvailablePoint.course_sheet_points(course, sheets)
{
sheets: sheets.map do |sheet|
{
name: sheet,
total_awarded: (total_awarded[sheet] || 0),
total_available: (total_available[sheet] || 0)
}
end,
total_awarded: AwardedPoint.course_points(course, include_admins, current_user.administrator?),
total_available: AvailablePoint.course_points_of_exercises(course, visible_exercises),
awarded_for_user_and_sheet: per_user_and_sheet,
total_for_user: user_totals,
users: users
}
end
def sort_summary(summary, sorting)
if sorting == 'total_points'
summary[:users] = summary[:users].sort_by { |user| [-summary[:total_for_user][user.login].to_i, user.login] }
elsif sorting =~ /(.*)_points$/
sheet = Regexp.last_match(1)
summary[:users] = summary[:users].sort_by { |user| [-summary[:awarded_for_user_and_sheet][user.login][sheet].to_i, user.login] }
end
end
def set_organization
@organization = Organization.find_by(slug: params[:organization_id])
end
end