-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathpoints_controller.rb
More file actions
133 lines (114 loc) · 4.91 KB
/
points_controller.rb
File metadata and controls
133 lines (114 loc) · 4.91 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
# frozen_string_literal: true
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
return respond_unauthorized('Authentication required') if current_user.guest?
add_course_breadcrumb
add_breadcrumb 'Points'
if can?(:teach, @course)
@user_fields = UserField.all.select(&:show_in_participant_list?)
end
only_for_user = User.find_by(login: params[:username])
only_for_user = current_user unless can?(:teach, @course)
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 show
@sheetname = params[:id]
@course = Course.find(params[:course_id])
authorize! :see_points, @course
return respond_unauthorized('Authentication required') if current_user.guest?
if can?(:teach, @course)
@user_fields = UserField.all.select(&:show_in_participant_list?)
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, 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
@users = [current_user] unless can?(:teach, @course)
respond_to do |format|
format.html
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, email, 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, only_for_user)
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?, only_for_user),
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