Skip to content

Commit

Permalink
Merge 2d7e9d3 into 788245c
Browse files Browse the repository at this point in the history
  • Loading branch information
pratikkumar-jain committed May 6, 2019
2 parents 788245c + 2d7e9d3 commit 3f5c26d
Show file tree
Hide file tree
Showing 14 changed files with 1,068 additions and 137 deletions.
Binary file added app/assets/images/lightbulb.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/music_note.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
550 changes: 550 additions & 0 deletions app/controllers/_resp_ctrl_old.rb

Large diffs are not rendered by default.

262 changes: 205 additions & 57 deletions app/controllers/response_controller.rb
Expand Up @@ -2,6 +2,8 @@ class ResponseController < ApplicationController
helper :submitted_content
helper :file

require 'net/http'

def action_allowed?
response = user_id = nil
action = params[:action]
Expand Down Expand Up @@ -74,28 +76,13 @@ def edit
render action: 'response'
end



# Update the response and answers when student "edit" existing response
def update
render nothing: true unless action_allowed?
# the response to be updated
@response = Response.find(params[:id])
msg = ""
begin
@map = @response.map
@response.update_attribute('additional_comment', params[:review][:comments])
@questionnaire = set_questionnaire
questions = sort_questions(@questionnaire.questions)
create_answers(params, questions) unless params[:responses].nil? # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)
@response.update_attribute('is_submitted', true) if params['isSubmit'] && params['isSubmit'] == 'Yes'
@response.notify_instructor_on_difference if (@map.is_a? ReviewResponseMap) && @response.is_submitted && @response.significant_difference?
rescue StandardError
msg = "Your response was not saved. Cause:189 #{$ERROR_INFO}"
end
ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, "Your response was submitted: #{@response.is_submitted}", request)
redirect_to controller: 'response', action: 'save', id: @map.map_id,
return: params[:return], msg: msg, review: params[:review], save_options: params[:save_options]
is_submitted = params[:isSubmit].present?
@save_type = params[:save_type]
# An AJAX call can be made from the response view due to JS implementation
save_response("update")
end

def new
Expand Down Expand Up @@ -138,45 +125,13 @@ def view
set_content
end

# NEW Change: when creating (not in db yet) a response Submit is clicked,
# instead of immediately redirecting, first confirm the input response
def create
map_id = params[:id]
map_id = params[:map_id] unless params[:map_id].nil? # pass map_id as a hidden field in the review form
@map = ResponseMap.find(map_id)
if params[:review][:questionnaire_id]
@questionnaire = Questionnaire.find(params[:review][:questionnaire_id])
@round = params[:review][:round]
else
@round = nil
end
is_submitted = (params[:isSubmit] == 'Yes')
was_submitted = false
# There could be multiple responses per round, when re-submission is enabled for that round.
# Hence we need to pick the latest response.
@response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first
if @response.nil?
@response = Response.create(
map_id: @map.id,
additional_comment: params[:review][:comments],
round: @round.to_i,
is_submitted: is_submitted
)
end
was_submitted = @response.is_submitted
@response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted) # ignore if autoupdate try to save when the response object is not yet created.

# ,:version_num=>@version)
# Change the order for displaying questions for editing response views.
questions = sort_questions(@questionnaire.questions)
create_answers(params, questions) if params[:responses]
msg = "Your response was successfully saved."
error_msg = ""
# only notify if is_submitted changes from false to true
if (@map.is_a? ReviewResponseMap) && (was_submitted == false && @response.is_submitted) && @response.significant_difference?
@response.notify_instructor_on_difference
@response.email
end
redirect_to controller: 'response', action: 'save', id: @map.map_id,
return: params[:return], msg: msg, error_msg: error_msg, review: params[:review], save_options: params[:save_options]
save_type = params[:save_type]
# An AJAX call can made from the response view due to JS implementation
save_response('create')
end

def save
Expand All @@ -195,6 +150,7 @@ def save
AwardedBadge.where(participant_id: participant.id, badge_id: badge_id, approval_status: 0).first_or_create
end
end

ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, "Response was successfully saved")
redirect_to action: 'redirect', id: @map.map_id, return: params[:return], msg: params[:msg], error_msg: params[:error_msg]
end
Expand Down Expand Up @@ -264,7 +220,199 @@ def pending_surveys
end
end
end

# Adding a function to integrate suggestion detection algorithm (SDA)
def get_review_response_metrics
uri = URI.parse('https://peer-review-metrics-nlp.herokuapp.com/metrics/all')
http = Net::HTTP.new(uri.hostname, uri.port)
req = Net::HTTP::Post.new(uri, initheader = {'Content-Type' =>'application/json'})
req.body = {"reviews"=>@all_comments,
"metrics"=>["suggestion", "sentiment"]}.to_json
http.use_ssl = true
@all_comments = [""] if @all_comments.empty?
begin
res = http.request(req)
if (res.code == "200" && res.content_type == "application/json")
return JSON.parse(res.body)
else
return nil
end
rescue StandardError
return nil
end
end

def show_confirmation_page
flash[:error] = params[:error_msg] unless params[:error_msg] and params[:error_msg].empty?
flash[:note] = params[:msg] unless params[:msg] and params[:msg].empty?

@response = Response.find(params[:id])
@metric = Metric.new

# a response should already exist when viewing this page
render nothing:true unless @response
@all_comments = []

# NEW change: since response already saved
# fetch comments from Answer model in db instead
answers = Answer.where(response_id: @response.id)
answers.each do |a|
comment = a.comments
comment.slice! "<p>"
comment.slice! "</p>"
@all_comments.push(comment) unless comment.empty?
end

# send user review to API for analysis
@api_response = get_review_response_metrics

#compute average for all response fields in ONE response
suggestion_chance = 0
suggestion_sentiment_score = 0

if @api_response
number_of_responses = @api_response["results"].size
0.upto(number_of_responses- 1) do |i|
suggestion_chance += @api_response["results"][i]["metrics"]["suggestion"]["suggestions_chances"]
suggestion_sentiment_score += @api_response["results"][i]["metrics"]["sentiment"]["sentiment_score"]
end
@avg_suggestion_chance_for_response = suggestion_chance/number_of_responses
@avg_suggestion_chance_for_response = @avg_suggestion_chance_for_response.to_i
avg_sentiment_score_for_response = suggestion_sentiment_score/number_of_responses
@sentiment_keyword_for_response = @metric.get_sentiment_text(avg_sentiment_score_for_response) #get text
else
# no comments were received - API call is not made
@avg_suggestion_chance_for_response = 0;
@sentiment_keyword_for_response = @metric.get_sentiment_text(0)
end

@assignment_suggestion_average = -1;
# compute average
@map = ResponseMap.find(@response.map_id)
# below is class avg (suggestion score)for this assignment
@assignment_suggestion_average = @metric.suggestion_chance_average(@map.reviewed_object_id) #pass assignment id

if (@assignment_suggestion_average < 0) #if no class average found, display current score as average
@assignment_suggestion_average = @avg_suggestion_chance_for_response
end
end

def save_response(http_method)
case http_method
when "create"
create_response
when "update"
update_response
end
end

def create_response
# NEW change: is_submitted is always false for create.
is_submitted = false

map_id = params[:id]
map_id = params[:map_id] unless params[:map_id].nil? # pass map_id as a hidden field in the review form
@map = ResponseMap.find(map_id)
if params[:review][:questionnaire_id]
@questionnaire = Questionnaire.find(params[:review][:questionnaire_id])
@round = params[:review][:round]
else
@round = nil
end
# There could be multiple responses per round, when re-submission is enabled for that round.
# Hence we need to pick the latest response.
@response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first
if @response.nil?
@response = Response.create(
map_id: @map.id,
additional_comment: params[:review][:comments],
round: @round.to_i,
is_submitted: is_submitted
)
end

was_submitted = @response.is_submitted
@response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted) # ignore if autoupdate try to save when the response object is not yet created.

# ,:version_num=>@version)
# Change the order for displaying questions for editing response views.
questions = sort_questions(@questionnaire.questions)
create_answers(params, questions) if params[:responses]
msg = "Your response was successfully saved."
error_msg = ""
# only notify if is_submitted changes from false to true
if (@map.is_a? ReviewResponseMap) && (was_submitted == false && @response.is_submitted) && @response.significant_difference?
@response.notify_instructor_on_difference
@response.email
end

button_type = params[:button_type]

if button_type == "submit_button"
redirect_to action: 'show_confirmation_page', id: @response.id, return: @return, msg: msg
else
# save button pressed
# auto save button will not process redirect/render since it's an AJAX call
redirect_to controller: 'response', action: 'save', id: @map.map_id,
return: params[:return], msg: msg, error_msg: error_msg, review: params[:review], save_options: params[:save_options]
end
end

def update_response
# the response to be updated
@response = Response.find(params[:id])
@map = @response.map
msg = ""
submit_response_confirmed = params[:is_submitted] && params[:is_submitted] == "Yes"
button_type = params[:button_type]

if submit_response_confirmed
# is_submitted is 'Yes' only when submit button in confirmation page is clicked
save_confirmed_response
msg = "Your response was submitted"
params[:msg] = msg
# log success
ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, msg, request)
# redirect to save method...which then redirects again
redirect_to controller: 'response', action: 'save', id: @map.map_id,
return: params[:return], msg: msg, review: params[:review], save_options: params[:save_options]
elsif button_type && button_type == "submit_button"
# is_submitted is 'Yes' only when submit button in confirmation page is clicked
save_unconfirmed_response
msg = "Response was successfully saved"
# log success
ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, msg, request)
redirect_to action: 'show_confirmation_page', id: @response.id, return: @return, msg: msg
else
save_unconfirmed_response
msg = "Response was successfully saved"
params[:msg] = msg
ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, msg)
# redirect to save method...which then redirects again
redirect_to controller: 'response', action: 'save', id: @map.map_id,
return: params[:return], msg: msg, review: params[:review], save_options: params[:save_options]
end
end

def save_confirmed_response
@response.update_attribute('is_submitted', true) if params['is_submitted'] && params['is_submitted'] == 'Yes'
@response.notify_instructor_on_difference if (@map.is_a? ReviewResponseMap) && @response.is_submitted && @response.significant_difference?
Metric.new.update_suggestion_chance(@response, params["avg_suggestion_chance_for_response"])
end

def save_unconfirmed_response
begin
#@map = @response.map
@response.update_attribute('additional_comment', params[:review][:comments])
@questionnaire = set_questionnaire
questions = sort_questions(@questionnaire.questions)
# for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)
create_answers(params, questions) unless params[:responses].nil?
rescue StandardError
params[:error_msg] = "Your response was not saved. Cause:189 #{$ERROR_INFO}"
end
end

private

# new_response if a flag parameter indicating that if user is requesting a new rubric to fill
Expand Down Expand Up @@ -369,4 +517,4 @@ def init_answers(questions)
Answer.create(response_id: @response.id, question_id: q.id, answer: nil, comments: '') if a.nil?
end
end
end
end
6 changes: 3 additions & 3 deletions app/helpers/review_mapping_helper.rb
Expand Up @@ -237,12 +237,12 @@ def display_volume_metric_chart(reviewer)
yAxes: [{
stacked: true,
id: "bar-y-axis1",
barThickness: 10
barThickness: 8
}, {
display: false,
stacked: true,
id: "bar-y-axis2",
barThickness: 15,
barThickness: 8,
type: 'category',
categoryPercentage: 0.8,
barPercentage: 0.9,
Expand All @@ -254,7 +254,7 @@ def display_volume_metric_chart(reviewer)
stacked: false,
ticks: {
beginAtZero: true,
stepSize: 50,
stepSize: 200,
max: 400
}
}]
Expand Down
39 changes: 39 additions & 0 deletions app/models/metric.rb
@@ -0,0 +1,39 @@
class Metric < ActiveRecord::Base


def update_suggestion_chance(response, suggestion_chance)
response.suggestion_chance_percentage = suggestion_chance;
response.save!
end

def suggestion_chance_average(assignment)
# this method will compute the suggestion_chances average for all responses for the particular assignment
# if no responses exist for particular assignment, return -1 as average suggestion chance
# make a list of responses for a particular assignment
responses = []
response_map_list = ResponseMap.where(reviewed_object_id: assignment)
response_map_list.each do |rm|
responses += Response.where(map_id: rm.id) # get response for
end
#sum up the suggestion chance percentages
sum = 0
not_nil_count = 0
responses.each do |r|
if !r.suggestion_chance_percentage.nil?
sum += r.suggestion_chance_percentage
not_nil_count += 1
end
end
#return average
if not_nil_count > 0
return sum / not_nil_count
end
return -1
end

def get_sentiment_text(avg_sentiment_for_response)
#convert average into keyword
(avg_sentiment_for_response < -0.3) ? "Negative":(avg_sentiment_for_response > 0.3)?"Positive":"Neutral"
end

end

0 comments on commit 3f5c26d

Please sign in to comment.