-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes to assignment upload to fix exisitng bugs and add new features (Part 1) #82
base: master
Are you sure you want to change the base?
Changes from 6 commits
767a8be
0920c9b
cfdce3b
01fb940
eeff682
24e098a
c5ac153
526a11c
b44641c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -180,4 +180,4 @@ body.submission_similarities_show { | |
} | ||
} | ||
} | ||
} | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
class ApplicationMailer < ActionMailer::Base | ||
default from: 'from@example.com' | ||
default from: '' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have a default configurable address? Is this line necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems related to L4-5 in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will address this in the next PR which will include progress bar, assignment timeout and email functionalites. |
||
layout 'mailer' | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class AssignmentMailer < ApplicationMailer | ||
|
||
def assignment_email | ||
@email_title = params[:email_title] | ||
mail(to: '', subject: email_title) | ||
end | ||
|
||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ class Assignment < ActiveRecord::Base | |
has_many :confirmed_or_suspected_plagiarism_cases, -> { where("status = #{SubmissionSimilarity::STATUS_CONFIRMED_AS_PLAGIARISM} OR status = #{SubmissionSimilarity::STATUS_SUSPECTED_AS_PLAGIARISM}") }, class_name: "SubmissionSimilarity" | ||
has_many :confirmed_plagiarism_cases, -> { where("status = #{SubmissionSimilarity::STATUS_CONFIRMED_AS_PLAGIARISM}") }, class_name: "SubmissionSimilarity" | ||
has_many :submissions | ||
|
||
belongs_to :course | ||
|
||
validates :title, :language, :min_match_length, :ngram_size, presence: true | ||
|
@@ -51,10 +52,19 @@ class Assignment < ActiveRecord::Base | |
ocaml: "ocaml" | ||
} | ||
|
||
FILE_STRUCTURES = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add comment as to what this FILE_STRUCTURES enum is doing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have added some comments. |
||
all: "By Files", | ||
dir: "By Directory" | ||
} | ||
|
||
def self.options_for_languages | ||
LANGUAGES.to_a.collect { |pair| pair.reverse } | ||
end | ||
|
||
def self.options_for_file_structure | ||
FILE_STRUCTURES.to_a.collect { |pair| pair.reverse } | ||
end | ||
|
||
def prettify_js_lang | ||
"lang-#{PRETTIFY_LANGUAGES[self.language]}" | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /> | ||
</head> | ||
<body> | ||
<p> The assignment you uploaded has completed processing. </p> | ||
<p> Please view the outcome at <%= @assignment_url %></p> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
</ul> | ||
</div> | ||
<% end %> | ||
<p> Hover over ⓘ for more details about any terminology.</p> | ||
<div> | ||
<%= f.label :title %> | ||
<%= f.text_field :title %> | ||
|
@@ -18,40 +19,73 @@ | |
<%= f.select :language, Assignment.options_for_languages %> | ||
</div> | ||
<div> | ||
<%= f.label :min_match_length, "Minimum Match Length [?]" , title: "For Java, only '.java' files will be processed." %> | ||
<%= f.label :min_match_length, "Minimum Match Length \u24D8" , title: "The least number of contiguous identical statements required to flag a match." %> | ||
<%= f.text_field :min_match_length %> | ||
</div> | ||
<div> | ||
<%= f.label :ngram_size, "Size of n-gram [?]", title: "An n-gram is a contiguous subsequence of n tokens of a given sequence." %> | ||
<%= f.label :ngram_size, "Size of n-gram \u24D8", title: "An n-gram is a contiguous subsequence of n tokens of a given sequence." %> | ||
<%= f.text_field :ngram_size %> | ||
</div> | ||
<div> | ||
<%= f.label :file, "Student submissions (zip) [?]", title: "The zip file should contain one folder for each student's code files; folders are named according to student ID; Name your folder as \"skeleton\" for the codes you wish to exclude from the system" %> | ||
<%= f.label :file_structure, "File Structure \u24D8", title: "This refers to the way the files are arranged in your zip folder. \n\nTo recursively search for all files in the provided directories and compare every file with each other file, select \"By Files\". \n\nInstead, if you don't want to compare files in the same leaf directory (for example, if the zip file is split into per-student directories and you don't care about self plagiarism, select \"By Directory\"" %> | ||
<%= f.select :file_structure, Assignment.options_for_file_structure %> | ||
</div> | ||
<div> | ||
<%= f.label :file, "Student submissions (zip) \u24D8", title: "The zip file should contain files according to the way you selected the \"File Structure \" option above. \n\nIf you selected \"By Files\", then, all the files in the zip folder will be compared with each other. Name your file as \"skeleton \" for the codes you wish to exclude from the system \n\nIf you selected the other option (\"By Directory\"), ensure that the zip file contains one folder for each student's code files. Ensure that the folders are named according to student ID and name your folder as \"skeleton\" for the codes you wish to exclude from the system" %> | ||
<%= f.file_field :file %> | ||
</div> | ||
|
||
|
||
<div> | ||
<%= f.label :mapbox, "Upload map file?" %> | ||
<%= f.label :mapbox, "Add more options? \u24D8", title: "Check the box to include additional optional options"%> | ||
<%= f.check_box :mapbox,{}, "Yes", "No"%> | ||
</div> | ||
<div id="map_file_details" style="display:none;"> | ||
<%= f.label :mapfile, "Mapping file (csv) [?]", title: "The zip file should contain one folder for each student's code files; folders are named according to student ID; Name your folder as \"skeleton\" for the codes you wish to exclude from the system" %> | ||
<%= f.label :mapfile, "Mapping file (csv) \u24D8", title: "If you have a map file that maps the filenames to other attributes such as student's names, github handle etc, upload the file here. Ensure that the file is a csv file and follows the conventions according to the user guide." %> | ||
<%= f.file_field :mapfile, accept: '.csv' %> | ||
|
||
</div> | ||
<div id="file_to_ignore_details" style="display:none;"> | ||
<%= f.label :filesIgnore, "Files to be ignored \u24D8" , title: "If you want to ignore certain files from the code zip file that you uploaded, add those filenmes under here. \n\nIf you want to ignore filenames that exactly match a certain filename, enter the filename as it is. For instance, entering \"question1\", will mean that all the filenames that are named as \"question1\" (irrespective of their file extensions) will all be ignored. \n\nIf you want to ignore filenames that partially contain a substring, add \"/ \" in front of the filename. For instance, if you enter, \"/question1\", filenames such as \"alice_question1.py\", \"bob_question1Test.c\", \"question1_charlie.java\" will all get ignored. \n\nIf you need to add muliple regex, leave a space in between them. For instance, if you enter \"question1 /question2 \", filesnames that either exactly match \"question1 \" or contain the substring \"question2 \" will all get ignored" %> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any suggested defaults? .pdf .doc(x)? .bin .ps There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to ignore code files. For non code files like pdf and doc files, these files will naturally get ignored without any users' input. |
||
<%= f.text_field :filesIgnore %> | ||
</div> | ||
<div id="file_to_process_details" style="display:none;"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May need to be clear which of |
||
<%= f.label :filesProcess, "Files to be only processed \u24D8" , title: "If you want to process and compare only certain files from the code zip file that you uploaded, add those filenmes under here. \n\nIf you want to process filenames that exactly match a certain filename, enter the filename as it is. For instance, entering \"question1\", will mean that all the filenames that are named as \"question1\" (irrespective of their file extensions) will all be processed and the rest will be ignored. \n\nIf you want to only process filenames that partially contain a substring, add \"/ \" in front of the filename. For instance, if you enter, \"/question1\", filenames such as \"alice_question1.py\", \"bob_question1Test.c\", \"question1_charlie.java\" will all get processed and the rest that does not contain the substring will all get ignored. \n\nIf you need to add muliple regex, leave a space in between them. For instance, if you enter \"question1 /question2 \", filesnames that either exactly match \"question1 \" or contain the substring \"question2 \" will all get processed." %> | ||
<%= f.text_field :filesProcess %> | ||
</div> | ||
<div id="ref_dir_details" style="display:none;"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will need to point to documentation about how this works. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will create an issue to update user guide so that I can add documentation for all newly added changes. |
||
<%= f.label :refDir, "Reference Directory (zip) \u24D8", title: "If you have additional files that you want to compare, but do not want to check for plagiarism (for example, if you want to also compare submissions from previous semesters), zip those files and upload it here." %> | ||
<%= f.file_field :refDir %> | ||
</div> | ||
<div id="email_details" style="display:none;"> | ||
<%= f.label :email, "Send email upon completion \u24D8" , title: "If you want to receive an email to notify you after the assignment has been processed, enter the email here. Ensure that you enter a valid email." %> | ||
<%= f.text_field :email %> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fill in with user's default email, to be edited? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, I have changed it accordingly. |
||
</div> | ||
<div> | ||
<%= f.submit class: "submit" %> | ||
<%= f.submit 'Create Assignment', name: 'create' %> | ||
<%= f.submit 'Preview Uploaded Code Files', name: 'preview' %> | ||
</div> | ||
<% end %> | ||
|
||
<script type="text/javascript"> | ||
var checkbox = document.getElementById('assignment_mapbox'); | ||
var details_div = document.getElementById('map_file_details'); | ||
var map_details_div = document.getElementById('map_file_details'); | ||
var files_ignore_details_div = document.getElementById('file_to_ignore_details'); | ||
var files_process_details_div = document.getElementById('file_to_process_details'); | ||
var ref_dir_details_div = document.getElementById('ref_dir_details'); | ||
var email_details_div = document.getElementById('email_details'); | ||
checkbox.onchange = function() { | ||
if(this.checked) { | ||
details_div.style['display'] = 'block'; | ||
map_details_div.style['display'] = 'block'; | ||
files_ignore_details_div.style['display'] = 'block'; | ||
files_process_details_div.style['display'] = 'block'; | ||
ref_dir_details_div.style['display'] = 'block'; | ||
email_details.style['display'] = 'block'; | ||
} else { | ||
details_div.style['display'] = 'none'; | ||
map_details_div.style['display'] = 'none'; | ||
files_ignore_details_div.style['display'] = 'none'; | ||
files_process_details_div.style['display'] = 'none'; | ||
ref_dir_details_div.style['display'] = 'none'; | ||
email_details.style['display'] = 'none'; | ||
} | ||
}; | ||
</script> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>jQuery UI Dialog - Modal message</title> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix title, even if not shown. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed the title accordingly. |
||
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> | ||
<style> | ||
h1 { font-size: 1.2em; margin: .6em 0; } | ||
div#users-contain { width: 600px; margin: 20px 0; } | ||
div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; } | ||
div#users-contain table td, div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; } | ||
.ui-dialog .ui-state-error { padding: .3em; } | ||
.validateTips { border: 1px solid transparent; padding: 0.3em; } | ||
</style> | ||
<script src="https://code.jquery.com/jquery-1.12.4.js"></script> | ||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> | ||
<script> | ||
$( function() { | ||
$( "#dialog-message" ).dialog({ | ||
modal: true, | ||
height: 700, | ||
width: 700, | ||
buttons: { | ||
'Reupload New Code Zip File': function() { | ||
$( this ).dialog( "close" ); | ||
}, | ||
'Create Assignment': function() { | ||
$("#form").submit(); | ||
} | ||
} | ||
}); | ||
|
||
var cal = document.getElementById('myHeader').innerText; | ||
console.log(cal) | ||
|
||
$(".ui-dialog-buttonpane button:contains('Create Assignment')") | ||
.button((cal == "SSID cannot process the assignment due to empty/insufficient files to compare") ? "disable" : "enable"); | ||
|
||
|
||
} ); | ||
</script> | ||
</head> | ||
<body> | ||
|
||
<h2>Assignment title: <%= @assignment.title %></h2> | ||
|
||
<pre> | ||
Language: <%= @assignment.language%> | ||
Min Match Length: <%= @assignment.min_match_length%> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggested defaults and \u24D8 for this line and next? |
||
NGram Size: <%= @assignment.ngram_size%> | ||
</pre> | ||
|
||
<% if @assignment.errors.any? %> | ||
<div id="error_explanation"> | ||
<h3><%= pluralize(@assignment.errors.count, "error") %> prohibited this assignment from being saved:</h3> | ||
<ul> | ||
<% @assignment.errors.full_messages.each do |msg| %> | ||
<li><%= msg %></li> | ||
<% end %> | ||
</ul> | ||
</div> | ||
<% end %> | ||
|
||
<%= form_for([@course, @assignment], :id => 'form') do |f| %> | ||
<div> | ||
<%= f.label :file_structure, "File Structure \u24D8", title: "This refers to the way the files are arranged in your zip folder. \n\nTo recursively search for all files in the provided directories and compare every file with each other file, select \"By Files\". \n\nInstead, if you don't want to compare files in the same leaf directory (for example, if the zip file is split into per-student directories and you don't care about self plagiarism, select \"By Directory\"" %> | ||
<%= f.select :file_structure, Assignment.options_for_file_structure %> | ||
</div> | ||
<div> | ||
<%= f.label :file, "Student submissions (zip) [?]", title: "The zip file should contain one folder for each student's code files; folders are named according to student ID; Name your folder as \"skeleton\" for the codes you wish to exclude from the system" %> | ||
<%= f.file_field :file %> | ||
</div> | ||
|
||
<div> | ||
<%= f.label :mapbox, "Add more options? \u24D8", title: "Check the box to include additional optional options"%> | ||
<%= f.check_box :mapbox,{}, "Yes", "No"%> | ||
</div> | ||
<div id="map_file_details" style="display:none;"> | ||
<%= f.label :mapfile, "Mapping file (csv) \u24D8", title: "If you have a map file that maps the filenames to other attributes such as student's names, github handle etc, upload the file here. Ensure that the file is a csv file and follows the conventions according to the user guide." %> | ||
<%= f.file_field :mapfile, accept: '.csv' %> | ||
</div> | ||
<div id="file_to_ignore_details" style="display:none;"> | ||
<%= f.label :filesIgnore, "Files to be ignored \u24D8" , title: "If you want to ignore certain files from the code zip file that you uploaded, add those filenmes under here. \n\nIf you want to ignore filenames that exactly match a certain filename, enter the filename as it is. For instance, entering \"question1\", will mean that all the filenames that are named as \"question1\" (irrespective of their file extensions) will all be ignored. \n\nIf you want to ignore filenames that partially contain a substring, add \"/ \" in front of the filename. For instance, if you enter, \"/question1\", filenames such as \"alice_question1.py\", \"bob_question1Test.c\", \"question1_charlie.java\" will all get ignored. \n\nIf you need to add muliple regex, leave a space in between them. For instance, if you enter \"question1 /question2 \", filesnames that either exactly match \"question1 \" or contain the substring \"question2 \" will all get ignored" %> | ||
<%= f.text_field :filesIgnore, {:value => @assignment.filesIgnore} %> | ||
</div> | ||
<div id="file_to_process_details" style="display:none;"> | ||
<%= f.label :filesProcess, "Files to be only processed \u24D8" , title: "If you want to process and compare only certain files from the code zip file that you uploaded, add those filenmes under here. \n\nIf you want to process filenames that exactly match a certain filename, enter the filename as it is. For instance, entering \"question1\", will mean that all the filenames that are named as \"question1\" (irrespective of their file extensions) will all be processed and the rest will be ignored. \n\nIf you want to only process filenames that partially contain a substring, add \"/ \" in front of the filename. For instance, if you enter, \"/question1\", filenames such as \"alice_question1.py\", \"bob_question1Test.c\", \"question1_charlie.java\" will all get processed and the rest that does not contain the substring will all get ignored. \n\nIf you need to add muliple regex, leave a space in between them. For instance, if you enter \"question1 /question2 \", filesnames that either exactly match \"question1 \" or contain the substring \"question2 \" will all get processed." %> | ||
<%= f.text_field :filesProcess, {:value => @assignment.filesProcess} %> | ||
</div> | ||
<div id="ref_dir_details" style="display:none;"> | ||
<%= f.label :refDir, "Reference Directory (zip) \u24D8", title: "If you have additional files that you want to compare, but do not want to check for plagiarism (for example, if you want to also compare submissions from previous semesters), zip those files and upload it here." %> | ||
<%= f.file_field :refDir %> | ||
</div> | ||
<div id="email_details" style="display:none;"> | ||
<%= f.label :email, "Send email upon completion \u24D8" , title: "If you want to receive an email to notify you after the assignment has been processed, enter the email here. Ensure that you enter a valid email." %> | ||
<%= f.text_field :email, {:value => @assignment.email} %> | ||
</div> | ||
<div> | ||
<%= f.submit 'Create Assignment', name: 'create' %> | ||
<%= f.submit 'Preview Uploaded Code Files', name: 'preview' %> | ||
</div> | ||
<% end %> | ||
|
||
<script type="text/javascript"> | ||
var checkbox = document.getElementById('assignment_mapbox'); | ||
var map_details_div = document.getElementById('map_file_details'); | ||
var files_ignore_details_div = document.getElementById('file_to_ignore_details'); | ||
var files_process_details_div = document.getElementById('file_to_process_details'); | ||
var ref_dir_details_div = document.getElementById('ref_dir_details'); | ||
var email_details_div = document.getElementById('email_details'); | ||
checkbox.onchange = function() { | ||
if(this.checked) { | ||
map_details_div.style['display'] = 'block'; | ||
files_ignore_details_div.style['display'] = 'block'; | ||
files_process_details_div.style['display'] = 'block'; | ||
ref_dir_details_div.style['display'] = 'block'; | ||
email_details.style['display'] = 'block'; | ||
} else { | ||
map_details_div.style['display'] = 'none'; | ||
files_ignore_details_div.style['display'] = 'none'; | ||
files_process_details_div.style['display'] = 'none'; | ||
ref_dir_details_div.style['display'] = 'none'; | ||
email_details.style['display'] = 'none'; | ||
} | ||
}; | ||
</script> | ||
|
||
|
||
|
||
|
||
<div id="dialog-message" title="Uploaded File Preview"> | ||
<div id="users-contain" class="ui-widget"> | ||
<h1 id="myHeader"> <%= @statusStatement %> </h1> | ||
<h1 id="myHeader2"> <%= @previewStatement %> </h1> | ||
<p> | ||
Under "File Structure", if you have clicked "By Directory", please ensure that the zip file contains 1 root folder for each students' code. Otherwise, if you want to recursively search and compare the files with each other, please click "By Files" under "File Drectory" | ||
</p> | ||
<table id="users" class="ui-widget ui-widget-content"> | ||
<thead> | ||
<tr class="ui-widget-header "> | ||
<th> <%= @column1Title %> </th> | ||
<th> <%= @column2Title %> </th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<% @dirHash.each { |key, value| %> | ||
<tr> | ||
<td><%= key %></td> | ||
<td> | ||
<ul> | ||
<% value.each do |val| %> | ||
<li><%= val %></li> | ||
<% end %> | ||
</ul> | ||
</td> | ||
</tr> | ||
<% } %> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
|
||
|
||
</body> | ||
</html> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add nl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have completed the change.