代码查重功能增加,管理员界面增加代码测试列表.

yuanke_1
yuanke 9 years ago
parent ef5d8abf38
commit a8dce5e520

@ -556,4 +556,14 @@ class AdminController < ApplicationController
end
end
#代码测试列表
def code_work_tests
@code_work_tests = StudentWorkTest.find_by_sql("select a.* ,b.id as homeworkid,d.language from student_work_tests as a , homework_commons as b ,student_works as c, homework_detail_programings as d where a.student_work_id = c.id and b.id = c.homework_common_id and c.homework_common_id = d.homework_common_id order by a.created_at desc")
#@code_work_tests = StudentWorkTest.order('created_at desc')
@code_work_tests = paginateHelper @code_work_tests,30
@page = (params['page'] || 1).to_i - 1
respond_to do |format|
format.html
end
end
end

@ -885,6 +885,7 @@ class CoursesController < ApplicationController
@course_activities = course_activities.order('updated_at desc').limit(10).offset(@page * 10)
end
@type = params[:type]
respond_to do |format|
format.js
format.html{render :layout => 'base_courses'}
@ -925,6 +926,66 @@ class CoursesController < ApplicationController
end
end
def search_homework_member homeworks,name
if name == ""
select_homework = homeworks
else
name = name.downcase
select_homework = homeworks.select{ |homework|
homework.user[:login].to_s.downcase.include?(name) || homework.user.user_extensions[:student_id].to_s.downcase.include?(name) || (homework.user[:lastname].to_s.downcase + homework.user[:firstname].to_s.downcase).include?(name)
}
end
select_homework
end
# 作业查重
def code_repeat
#代码查重新加的
@order,@b_sort,@name,@group = params[:order] || "score",params[:sort] || "desc",params[:name] || "",params[:group]
@is_teacher = User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
@homework = HomeworkCommon.find params[:homework]
#order("#{@order} #{@b_sort}"
@student_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,IF(final_score = 0, 0, final_score - absence_penalty - late_penalty)) as score").order("simi_value desc"),@name
@works_hash = {}
@student_works.each do |tmpwork|
@works_hash[tmpwork.id] = tmpwork
end
#respond_to do |format|
#format.html {render :layout => 'base_courses'}
#end
end
def show_comparecode
src_id = params[:src_id]
dst_id = params[:dst_id]
src_work = StudentWork.where("id =?", src_id).first
@homework = HomeworkCommon.find params[:homework_id]
@src_code = src_work.description
src_user = User.where("id =?", src_work.user_id).first
@src_username = src_user.try(:realname) != " " ? src_user.lastname + src_user.firstname : src_user.try(:login)
#descriotion user name
dst_work = StudentWork.where("id =?", dst_id).first
@dst_code = dst_work.description
dst_user = User.where("id =?", dst_work.user_id).first
@dst_username = dst_user.try(:realname) != " " ? dst_user.lastname + dst_user.firstname : dst_user.try(:login)
respond_to do |format|
format.js
end
end
#根据已有课程复制课程
#param id:已有课程ID
def copy_course

@ -5,7 +5,7 @@ class StudentWorkController < ApplicationController
include ApplicationHelper
require 'bigdecimal'
require "base64"
before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :program_test,:program_test_ex,:set_score_rule,:forbidden_anonymous_comment,:delete_work,:new_student_work_project,:student_work_project,:cancel_relate_project,:search_course_students]
before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :program_test,:program_test_ex,:code_repeattest,:set_score_rule,:forbidden_anonymous_comment,:delete_work,:new_student_work_project,:student_work_project,:cancel_relate_project,:search_course_students]
before_filter :find_work, :only => [:edit, :update, :show, :destroy, :add_score, :praise_student_work,:retry_work,:revise_attachment]
before_filter :member_of_course, :only => [:new, :create, :show, :add_score, :praise_student_work]
before_filter :author_of_work, :only => [:edit, :update, :destroy]
@ -81,6 +81,8 @@ class StudentWorkController < ApplicationController
#根据传入的tIndex确定是第几次测试
#之后如果觉得很卡 可以改成将结果传回JS再以参数形式传回来
def program_test_ex
tStarttime = Time.now
is_test = params[:is_test] == 'true'
resultObj = {status: 0, results: [], error_msg: '', time: Time.now.strftime('%Y-%m-%d %T'),tseq:1,tcount:1,testid:1} #保存每测试一次返回的结果
@ -134,6 +136,16 @@ class StudentWorkController < ApplicationController
end
#每次从数据库取出上次的结果加上本次的结果再存入数据库
tEndtime = Time.now
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000+(tEndtime.usec - tStarttime.usec)/1000
if result["status"].to_i != -2
result["results"].first['user_wait'] = tUsedtime
end
if result["results"][0]["status"].to_i == 2
result["status"] = 2
end
status = result["status"]
if index == 1
student_work_test = student_work.student_work_tests.build(status: status,
@ -162,6 +174,11 @@ class StudentWorkController < ApplicationController
resultObj[:index] = student_work.student_work_tests.count
end
tEndtime = Time.now
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000+(tEndtime.usec - tStarttime.usec)/1000
logger.debug "program_test_ex user wait time = #{tUsedtime} 毫秒"
#渲染返回结果
render :json => resultObj
end
@ -169,6 +186,106 @@ class StudentWorkController < ApplicationController
end
end
#找出该作业的所有提交作业
def find_all_student_work_by_homeid()
all_studentwork = StudentWork.where("homework_common_id =?", @homework.id)
all_studentwork
end
def request_code_repeattest(src)
url = "#{Redmine::Configuration['jplag_server']}api/realtime_test.json"
factor = []
src.each do |test|
factor << {work_id: test.id, des: test.description,created_at:test.created_at.to_i}
end
solutions = {
homeid:@homework.id,
language:@homework.homework_detail_programing.language,
factor: factor
}
uri = URI(url)
body = solutions.to_json
logger.debug "send body"
logger.debug body
res = Net::HTTP.new(uri.host, uri.port).start do |client|
request = Net::HTTP::Post.new(uri.path)
request.body = body
request["Content-Type"] = "application/json"
client.request(request)
end
JSON.parse(res.body)
end
#代码查重 status: 0完成 -2不需要查重 -1查重失败不支持该语言
def code_repeattest
tStarttime = Time.now
logger.debug "code_repeattest start is #{tStarttime}}"
resultObj = {status: -2}
@homework = HomeworkCommon.find params[:homework]
all_studentwork = find_all_student_work_by_homeid()
if all_studentwork == nil
resultObj[:status] = -2
elsif all_studentwork.count <= 1
resultObj[:status] = -2
else
#@homework.homework_detail_programing.language、id、description
logger.debug "time1 is #{Time.now.usec} "
result = request_code_repeattest(all_studentwork)
logger.debug "time2 is #{Time.now.usec} "
resultObj[:status] = result['status'].to_i
# resultObj[:results] = result['results']
#Time.now, simi_id = simiworkid , simi_value = simivalue
if resultObj[:status] == 0
@homework.simi_time = Time.now
resultObj[:comparetime] = @homework.simi_time
@homework.update_column('simi_time', @homework.simi_time)
logger.debug "time3 is #{Time.now.usec} "
result['results'].each do |key,value|
if value['simiworkid'].to_i > 0
@student_work = StudentWork.where("id =?", key.to_i).first
@student_work.update_column('simi_id', value['simiworkid'].to_i)
@student_work.update_column('simi_value', value['simivalue'].to_i)
end
# sqlstr = "update student_works set simi_id=#{value['simiworkid']},simi_value=#{value['simivalue']} where id=#{key.to_i} "
# dbh.execute(sqlstr)
end
logger.debug "time4 is #{Time.now.usec} "
end
end
tEndtime = Time.now
logger.debug "code_repeattest end is #{tEndtime}}"
tUsedtime = (tEndtime.to_i-tStarttime.to_i)*1000000+(tEndtime.usec - tStarttime.usec)
logger.debug "code_repeattest userd utime is #{tUsedtime}"
render :json => resultObj
end
def last_codecomparetime
resultObj = {status: 0}
@homework = HomeworkCommon.find params[:homework]
#转换一下
if @homework.simi_time != nil
resultObj[:comparetime] = Time.parse(@homework.simi_time.to_s).strftime("%Y-%m-%d %H:%M")
else
resultObj[:comparetime] = @homework.simi_time
end
render :json => resultObj
end
def index
# 作业消息状态更新
@ -351,6 +468,7 @@ class StudentWorkController < ApplicationController
render_403
return
end
@student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,IF(final_score = 0, 0, final_score - absence_penalty - late_penalty)) as score").order("#{@order} #{@b_sort}"),@name).count
end
@ -1152,6 +1270,7 @@ class StudentWorkController < ApplicationController
request["Content-Type"] = "application/json"
client.request(request)
end
JSON.parse(res.body)
end

@ -1,7 +1,7 @@
#老师布置的作业表
#homework_type: 0:普通作业;1:匿评作业;2:编程作业
class HomeworkCommon < ActiveRecord::Base
# attr_accessible :name, :user_id, :description, :publish_time, :end_time, :homework_type, :late_penalty, :course_id
# attr_accessible :name, :user_id, :description, :publish_time, :end_time, :homework_type, :late_penalty, :course_id,:simi_time
include Redmine::SafeAttributes
include ApplicationHelper

@ -1,6 +1,6 @@
#学生提交作品表
class StudentWork < ActiveRecord::Base
attr_accessible :name, :description, :homework_common_id, :user_id, :final_score, :teacher_score, :student_score, :teaching_asistant_score, :project_id, :is_test
attr_accessible :name, :description, :homework_common_id, :user_id, :final_score, :teacher_score, :student_score, :teaching_asistant_score, :project_id, :is_test, :simi_id, :simi_value
belongs_to :homework_common
belongs_to :user

@ -0,0 +1,96 @@
<h3>
<%=l(:label_code_work_tests)%>
</h3>
&nbsp;
<div class="autoscroll">
<table class="list" style="width: 100%;table-layout: fixed">
<thead>
<tr>
<th style="width: 50px;">
作业id
</th>
<th style="width: 60px;">
平均等待时间
</th>
<th style="width: 50px;">
语言
</th>
<th style="width: 120px;">
提交测试时间
</th>
<th style="width: 50px;">
答题状态
</th>
<th style="width: 50px;">
测试集数
</th>
<th style="width: 50px;">
最小耗时
</th>
<th style="width: 50px;">
最大耗时
</th>
</tr>
</thead>
<tbody>
<% @code_work_tests.each do |test| %>
<tr class="<%= cycle("odd", "even") %>">
<td style="text-align: center; " title='<%=test.homeworkid%>'>
<%=link_to(test.homeworkid, student_work_index_path(:homework => test.homeworkid))%>
</td>
<td style="text-align: center;">
<% if test.status != -2 && test.results.first['user_wait'] %>
<% wait_time = 0 %>
<% test.results.each do |result| wait_time = wait_time + result['user_wait'] end %>
<%=(wait_time/test.results.count).to_s+"毫秒" %>
<% else %>
<%="未记录"%>
<% end %>
</td>
<td align="center">
<%=%W(C C++ Python Java).at(test.language.to_i - 1)%>
</td>
<td align="center">
<%=Time.parse(test.created_at.to_s).strftime("%Y-%m-%d %H:%M:%S")%>
</td>
<td align="center">
<% if test.status == 0 %>
<%= "答题正确" %>
<% elsif test.status == -2 %>
<%= "编译错误" %>
<% elsif test.status == 2 || test.results.last['status'] == 2 %>
<%= "超时" %>
<% else %>
<%= "答题错误" %>
<% end %>
</td>
<td class="center">
<% if test.status != -2 %>
<%=test.results.count%>
<% end %>
</td>
<td class="center">
<% if test.status != -2 %>
<%test.results = test.results.sort_by {|result| result['time_used'] }%>
<%=test.results.first['time_used'] == 0 ? "1毫秒":test.results.first['time_used'].to_s+"毫秒"%>
<% end %>
</td>
<td class="center">
<% if test.status != -2 %>
<%=test.results.last['time_used'] == 0 ? "1毫秒":test.results.last['time_used'].to_s+"毫秒"%>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<div class="pagination">
<%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false %>
</div>
<% html_title(l(:label_code_work_tests)) -%>

@ -0,0 +1,101 @@
<div class="blue-border-box">
<div class="box-con">
<%if @homework.simi_time != nil %>
<h4 id = "compare-tips-1"><%="您上次查重的时间为"+Time.parse(@homework.simi_time.to_s).strftime("%Y-%m-%d %H:%M")%></h4>
<%end%>
<div class="box-con-a">
<a href="javascript:void(0);" class="Blue-btn fl " onclick = "compare_code_btn(<%=homework.id%>,<%=courseid%>)">重新查重</a>
<a href="javascript:void(0);" class="Blue-btn fl " onclick = "see_last_compare_code(<%=courseid%>,<%=homework.id%>)">查看结果</a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<script type="text/javascript">
//请求重新查重
function compare_code_btn(homeworkid,courseid)
{
hideModal($(".blue-border-box"));
test_repeat(homeworkid,courseid);
}
//查看结果
function see_last_compare_code(courseid,homeworkid)
{
hideModal($(".blue-border-box"));
var rootpath = getRootPath();
var code_repeatpath = rootpath+"/courses/"+courseid+"/code_repeat?homework="+homeworkid;
//新打开页面
window.open(code_repeatpath);
}
var test_repeat = function(homeworkid,courseid){
$.post(
'/student_work/code_repeattest',
{homework: homeworkid},
function(data,status){
console.log("result = ");
console.log(data);
if (data.status == 0) {
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"查重完成是否立即查看结果?",:status=>1, :homework=> homework,:courseid=> courseid})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
else if (data.status == -1){
// confirm("对不起只支持java/c/c++的代码查重!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起目前只支持java/c/c++的代码查重!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
else if (data.status == -2){
// confirm("对不起该作业的作品过少不能查重!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
return;
}
).fail(function(xhr, status){
// confirm("对不起,服务器繁忙请稍后再试!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> homework,:courseid=> courseid})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
return;
});
};
</script>

@ -0,0 +1,22 @@
<div class="blue-border-box">
<div class="box-con">
<h4><%=des%></h4>
<div class="box-con-a">
<a href="javascript:void(0);" class="Blue-btn " style="width:67px; margin:25px auto 0px auto;" onclick = "yes_btn(<%=status%>,<%=courseid%>,<%=homework.id%>)">确定</a>
</div>
<div class="cl"></div>
</div>
</div>
</div>
<script type="text/javascript">
function yes_btn(status,courseid,homeworkid)
{
hideModal($(".blue-border-box"));
if(status == 1) {
var rootpath = getRootPath();
var code_repeatpath = rootpath+"/courses/"+courseid+"/code_repeat?homework="+homeworkid;
window.open(code_repeatpath);
}
}
</script>

@ -0,0 +1,16 @@
<% content_for :header_tags do %>
<%= javascript_include_tag "/assets/codemirror/codemirror_python_ruby_c" %>
<%= stylesheet_link_tag "/assets/codemirror/codemirror" %>
<%= stylesheet_link_tag "/assets/codemirror/merge" %>
<%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"%>
<%= javascript_include_tag "/assets/codemirror/merge" %>
<% end %>
<article>
<h3 style="float:left; width:50%; text-align:center;"><%=src_name%></h3>
<h3 style="float:left; width:50%; text-align:center;"><%=dst_name%></h3><div class="cl"></div>
<pre id = "program-src_1" style = "display: none" ><%= src_code if src_code%></pre>
<pre id = "program-src_2" style = "display: none" ><%= dst_code if dst_code%></pre>
<div class = "program-compare-code" id=program-compare-code></div>
</article>

@ -0,0 +1,79 @@
<div class="conbox">
<h2 class="conbox-h2">查重结果</h2>
<div class="chabox">
<ul class="chabox-header">
<li class="chabox-w-500" style = "width:413px" >全部作品</li>
<li class="chabox-w-500" style = "width:585px" >对比作品</li>
<div class="cl"></div>
</ul>
<ul class="chabox-top">
<li class="chabox-w-151" >作品名称</li>
<li>姓名</li>
<li>学号 </li>
<li class="chabox-r-line">时间 </li>
<li class="chabox-w-151">作品名称</li>
<li>姓名</li>
<li>学号 </li>
<li class="chabox-r-line">时间 </li>
<li >相似度 </li>
<li >对比 </li>
</ul>
<%if @homework.homework_type == 2 %>
<% @student_works.each do |student_work|%>
<ul class="chabox-con" id = "chabox-con-<%=student_work.id%>" >
<% student_work_name = student_work.name.nil? || student_work.name.empty? ? student_work.user.show_name + '的作品' : student_work.name%>
<li class="chabox-w-151" ><%=student_work_name%></li>
<li><%=student_work.user.show_name%></li>
<li><%= student_work.user.user_extensions.nil? ? "--" : student_work.user.user_extensions.student_id%> </li>
<li class="chabox-r-line"><%= Time.parse(format_time(student_work.created_at)).strftime("%m-%d %H:%M")%></li>
<% if student_work.simi_id > 0 && @works_hash[student_work.simi_id] %>
<% simi_student_work = @works_hash[student_work.simi_id] %>
<% simi_student_work_name = simi_student_work.name.nil? || simi_student_work.name.empty? ? simi_student_work.user.show_name + '的作品' : simi_student_work.name%>
<li class="chabox-w-151"><%=simi_student_work_name%></li>
<li><%=simi_student_work.user.show_name%></li>
<li><%= simi_student_work.user.user_extensions.nil? ? "--" : simi_student_work.user.user_extensions.student_id%></li>
<li class="chabox-r-line"><%= Time.parse(format_time(simi_student_work.created_at)).strftime("%m-%d %H:%M")%></li>
<% if student_work.simi_value >= 90 %>
<li style = "color:red" ><%=student_work.simi_value%>%</li>
<% else %>
<li ><%=student_work.simi_value%>%</li>
<% end %>
<!--@works_hash[student_work.id].description -->
<!--<li ><a href="javascript:void(0);" target="_blank" class="cha-btn" onclick = "show_code_compare()">查看</a>-->
<li >
<%= link_to("查看", show_comparecode_course_path(:homework_id => @homework.id,:src_id => student_work.id,:dst_id => student_work.simi_id),:class => "cha-btn",:remote => true ) %>
</li>
<%else%>
<li class="chabox-w-151">无</li>
<li>--</li>
<li>--</li>
<li class="chabox-r-line">--</li>
<li >--</li>
<% end %>
</ul>
<%end%>
<%end%>
</div>
<div class="cl"></div>
</div>
<script type="text/javascript">
function show_code_compare() {
// $("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/show_compare_code' ,:locals => {:src_code=> 1,:src_name=> 2,:dst_name=> 3, :dst_code=> 4,:language=> 5,})%>');
// showModal('ajax-modal', '950px');
// $('#ajax-modal').siblings().remove();
// $('#ajax-modal').before("<a href='javascript:void(0)' onclick='closeModal();' style='margin-left: 935px;' class='resourceClose'></a>");
// $('#ajax-modal').parent().css("top", "20%").css("left", "26.5%").css("position", "absolute");
// $('#ajax-modal').parent().addClass("resourceUploadPopup");
// $('#ajax-modal').css("padding-left", "16px").css("padding-bottom", "16px");
//
// function closeModal() {
// hideModal($(".contrast-box"));
// }
}
</script>

@ -0,0 +1,101 @@
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/show_compare_code' ,:locals => {:src_code=> @src_code,:src_name=> @src_username,:dst_name=> @dst_username, :dst_code=> @dst_code,})%>');
showModal('ajax-modal', '1250px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='closeModal();' style='margin-left: 1235px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","20%").css("left","20%").css("position","absolute");
//$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px").css("padding-top","10px");
function closeModal(){
hideModal($(".program-compare-code"));
}
var program_name = "text/x-csrc";
var language = <%= @homework.language.to_i %>;
if (language == 1) {
program_name = 'text/x-csrc';
} else if(language==2){
program_name = 'text/x-c++src';
}else if(language==3){
program_name = 'text/x-cython';
} else if(language==4){
program_name = 'text/x-java';
}
//
//var editor_1 = CodeMirror(document.getElementById("program-code_1"), {
// mode: {name: program_name,
// version: 2,
// singleLineStringErrors: false},
// lineNumbers: true,
// indentUnit: 2,
// matchBrackets: true,
// readOnly: true,
// value: $("#program-src_1").text()
// }
//);
//
//var editor_2 = CodeMirror(document.getElementById("program-code_2"), {
// mode: {name: program_name,
// version: 2,
// singleLineStringErrors: false},
// lineNumbers: true,
// indentUnit: 2,
// matchBrackets: true,
// readOnly: true,
// value: $("#program-src_2").text()
// }
//);
var value, orig1, orig2, dv, panes = 2, highlight = true, connect = null, collapse = false;
function initUI() {
if (value == null) return;
var target = document.getElementById("program-compare-code");
target.innerHTML = "";
dv = CodeMirror.MergeView(target, {
value: value,
origLeft: panes == 3 ? orig1 : null,
orig: orig2,
lineNumbers: true,
mode: program_name,
highlightDifferences: highlight,
connect: connect,
collapseIdentical: collapse
});
}
function toggleDifferences() {
dv.setShowDifferences(highlight = !highlight);
}
value = $("#program-src_1").text();
orig1 = $("#program-src_1").text();
orig2 = $("#program-src_2").text();
initUI();
function mergeViewHeight(mergeView) {
function editorHeight(editor) {
if (!editor) return 0;
return editor.getScrollInfo().height;
}
return Math.max(editorHeight(mergeView.leftOriginal()),
editorHeight(mergeView.editor()),
editorHeight(mergeView.rightOriginal()));
}
function resize(mergeView) {
var height = mergeViewHeight(mergeView);
for(;;) {
if (mergeView.leftOriginal())
mergeView.leftOriginal().setSize(null, height);
mergeView.editor().setSize(null, height);
if (mergeView.rightOriginal())
mergeView.rightOriginal().setSize(null, height);
var newHeight = mergeViewHeight(mergeView);
if (newHeight >= height) break;
else height = newHeight;
}
mergeView.wrap.style.height = height + "px";
}

@ -1,10 +1,10 @@
<!-- 匿评作品列表,显示某一个作品的信息 -->
<ul class="hworkListRow" id="student_work_<%= student_work.id%>">
<% if @homework.homework_type != 3 %>
<% is_my_work = student_work.user == User.current%>
<% is_my_work = student_work.user == User.current%>
<% else %>
<% pro = @homework.student_work_projects.where(:user_id => User.current.id).first %>
<% is_my_work = pro && pro.student_work_id == student_work.id%>
<% pro = @homework.student_work_projects.where(:user_id => User.current.id).first %>
<% is_my_work = pro && pro.student_work_id == student_work.id%>
<% end %>
<li class="hworkList340 w465">
<ul>

@ -1,3 +1,4 @@
<div class="show_hwork_arrow"></div>
<div class="showHwork">
<ul>
@ -69,16 +70,14 @@
<span class="w60">正确输出:</span>
<span class="width120"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["output"]%></pre></span>
<% if x["status"].to_i == 2 %>
<span class="w50">耗时:</span>
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
<% end %>
<span class="w50">耗时:</span>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
<div class="cl"></div>
<% else %>
<span class="w60 c_green">测试正确!</span>
<!-- <span class="w50"> 耗时:</span> -->
<!-- <span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
<span style="width:360px;">&nbsp;</span>
<span class="w50">耗时:</span>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
<div class="cl"></div>
<% end %>
</li>

@ -18,6 +18,9 @@
<input type="text" id="course_student_name" value="<%= @name%>" placeholder="姓名、学号、邮箱" class="hworkSearchInput" onkeypress="SearchByName('<%= student_work_index_path(:homework => @homework.id)%>',event);"/>
<a class="hworkSearchIcon" id="search_in_student_work" onclick="SearchByName_1('<%= student_work_index_path(:homework => @homework.id)%>');" href="javascript:void(0)"></a>
</div>
<%if @homework.homework_type == 2 %>
<a href="javascript:void(0);" class="BlueCirBtn fr" data-course-id="<%=@course.id%>" data-homework-simi-time="<%=@homework.simi_time%>" data-homework-id="<%=@homework.id%>" id="test-program-repeat-btn" onclick = "code_repeat()">代码查重</a>
<% end %>
<%= select_tag(:student_work_in_group,options_for_select(course_group_list(@course),@group), {:class => "classSplit"}) unless course_group_list(@course).empty? %>
<% end%>
<span class="fr c_grey"> <a href="javascript:void(0);" class="linkGrey2" id="homework_info_show" style="display: none">[ 显示作业信息 ]</a> </span>
@ -45,6 +48,7 @@
<div class="cl"></div>
<% end%>
<script type="text/javascript">
$(function(){
<% if !@is_evaluation && (!@is_teacher || params[:show_work_id].present?) %>
<% work= params[:show_work_id].nil? ? @homework.student_works.where("user_id = ?",User.current.id).first : StudentWork.find(params[:show_work_id]) %>
@ -85,4 +89,146 @@
<% end %>
<% end %>
});
//代码查重
function code_repeat(){
var homework_id = <%=@homework.id%>;
var course_id = <%=@course.id%>;
console.log("course_id=",course_id);
console.log("homework_id=",homework_id);
if(<%= @stundet_works.count <=1 %>)
{
//弹框
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
return;
}
//先请求下上次查询的时间
$.post(
'/student_work/last_codecomparetime',
{homework: homework_id},
function(data,status){
if (data.status == 0) {
var homework_simi_time = data.comparetime;
if (!homework_simi_time){
//没进行过代码查重则直接查重
test_repeat();
}
else{
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_1',:locals => {:homework=> @homework,:courseid=> @course.id })%>');
$('#compare-tips-1').html('您上次查重的时间为'+homework_simi_time);
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
console.log(homework_simi_time);
function closeModal(){
hideModal($(".blue-border-box"));
}
}
}
}
).fail(function(xhr, status){
// confirm("对不起,服务器繁忙请稍后再试!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
return;
});
//请求查重
var test_repeat = function(){
$.post(
'/student_work/code_repeattest',
{homework: homework_id},
function(data,status){
console.log("result = ");
console.log(data);
if (data.status == 0) {
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"查重完成是否立即查看结果?",:status=>1, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
else if (data.status == -1){
// confirm("对不起只支持java/c/c++的代码查重!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起目前只支持java/c/c++的代码查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
else if (data.status == -2){
// confirm("对不起该作业的作品过少不能查重!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起该作业的作品过少不能查重!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
}
return;
}
).fail(function(xhr, status){
// confirm("对不起,服务器繁忙请稍后再试!");
$("#ajax-modal").html('<%= escape_javascript( render :partial => 'courses/compare_code_tips_2',:locals => {:des=>"对不起,服务器繁忙请稍后再试!",:status=>0, :homework=> @homework,:courseid=> @course.id})%>');
showModal('ajax-modal', '580px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("<a href='javascript:void(0)' onclick='hideModal();' style='margin-left: 560px;' class='resourceClose'></a>");
$('#ajax-modal').parent().css("top","40%").css("left","50%");
$('#ajax-modal').parent().addClass("resourceUploadPopup");
$('#ajax-modal').css("padding-left","16px").css("padding-bottom","16px");
function closeModal(){
hideModal($(".blue-border-box"));
}
return;
});
};
}
</script>

@ -2,7 +2,6 @@
<%= javascript_include_tag "/assets/codemirror/codemirror_python_ruby_c" %>
<%= javascript_include_tag 'homework','baiduTemplate' %>
<%= stylesheet_link_tag "/assets/codemirror/codemirror" %>
<% end %>
<script type="text/javascript">
$(function(){
@ -36,16 +35,17 @@
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["result"]!> </pre></span>
<span class="w60">正确输出:</span>
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["output"]!></pre></span>
<! if(results["status"]==2){!>
<!--<! if(results["status"]==2){!>-->
<span class="w50"> 耗时:</span>
<span class="w80"><pre><!=results["time_used"]!>毫秒</pre></span>
<!}!>
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
<!--<!}!>-->
<div class="cl"></div>
</li>
<!}else{!>
<span class="w60 c_green">测试正确!</span>
<!-- <span class="w50"> 耗时:</span> -->
<!-- <span class="w80"><pre><!=results["time_used"]!>微秒</pre></span> -->
<span style="width:480px;">&nbsp;</span>
<span class="w50"> 耗时:</span>
<span class="w80"><pre ><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
<div class="cl"></div>
</li>
@ -146,16 +146,17 @@
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["result"]%> </pre></span>
<span class="w60">正确输出:</span>
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%= x["output"] %></pre></span>
<% if x["status"].to_i == 2 %>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
<% end %>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
<div class="cl"></div>
</li>
<% else %>
<span class="w60 c_green">测试正确!</span>
<!-- <span class="w50"> 耗时:</span> -->
<!-- <span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
<span style="width:480px;">&nbsp;</span>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
<div class="cl"></div>
</li>
<% end %>

@ -25,16 +25,17 @@
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["result"]!> </pre></span>
<span class="w60">正确输出:</span>
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><!=results["output"]!></pre></span>
<! if(results["status"]==2){!>
<!--<! if(results["status"]==2){!>-->
<span class="w50"> 耗时:</span>
<span class="w80"><pre><!=results["time_used"]!>毫秒</pre></span>
<!}!>
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
<!--<!}!>-->
<div class="cl"></div>
</li>
<!}else{!>
<span class="w60 c_green">测试正确!</span>
<!-- <span class="w50"> 耗时:</span> -->
<!-- <span class="w80"><pre><!=results["time_used"]!>微秒</pre></span> -->
<span style="width:480px;">&nbsp;</span>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><!=results["time_used"]==0?1:results["time_used"]!>毫秒</pre></span>
<div class="cl"></div>
</li>
@ -113,16 +114,15 @@
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["result"]%> </pre></span>
<span class="w60">正确输出:</span>
<span class="w180"><pre style="white-space: pre-wrap; margin-right: 15px;"><%=x["output"]%></pre></span>
<% if x["status"].to_i == 2 %>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><%=x["time_used"]%>毫秒</pre></span>
<% end %>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"] %>毫秒</pre></span>
<div class="cl"></div>
</li>
<% else %>
<span class="w60 c_green">测试正确!</span>
<!--<span class="w50"> 耗时:</span> -->
<!--<span class="w80"><pre><%=x["time_used"]%>微秒</pre></span> -->
<span style="width:480px;">&nbsp;</span>
<span class="w50"> 耗时:</span>
<span class="w80"><pre><%=x["time_used"]==0?1:x["time_used"]%>毫秒</pre></span>
<div class="cl"></div>
</li>
<% end %>

@ -2122,4 +2122,7 @@ zh:
label_resource_download_times: 下载次数
label_resource_upload_author: 上传者
label_resource_belongs_course: 所属课程
label_resource_belongs_project: 所属项目
label_resource_belongs_project: 所属项目
#edit yk
label_code_work_tests: 代码测试列表

@ -274,6 +274,8 @@ RedmineApp::Application.routes.draw do
get 'evaluation_list'
# post 'set_program_score'
post 'program_test_ex'
post 'code_repeattest'
post 'last_codecomparetime'
post 'set_score_rule'
end
end
@ -968,6 +970,7 @@ RedmineApp::Application.routes.draw do
match 'admin/latest_login_users', as: :latest_login_users
match 'admin/latest_login_teachers', as: :latest_login_teachers
get 'admin/homework'
get 'admin/code_work_tests'
resources :auth_sources do
member do
@ -988,6 +991,7 @@ RedmineApp::Application.routes.draw do
get 'search_member', :action => 'search_member'
get 'file', :action => 'file', :as => 'file'
get 'feedback', :action => 'feedback', :as => 'course_feedback'
get 'code_repeat', :action => 'code_repeat', :as => 'code_repeat'
get 'member', :controller => 'courses', :action => 'member', :as => 'member'
get 'export_course_member_excel',:controller => 'courses',:action => 'export_course_member_excel'
get 'member_score', :to => 'courses#member_score'
@ -1014,10 +1018,10 @@ RedmineApp::Application.routes.draw do
get 'syllabus'
get 'search_public_orgs_not_in_course'
get "homework_search"
get "show_comparecode"
end
collection do
match 'join_private_courses', :via => [:get, :post]
end
match '/member', :to => 'courses#member', :as => 'member', :via => :get

@ -0,0 +1,6 @@
class AddSimiIdToStudentWorks < ActiveRecord::Migration
def change
add_column :student_works, :simi_id, :integer, :default => false
add_column :student_works, :simi_value, :integer, :default => false
end
end

@ -0,0 +1,5 @@
class AddSimiTimeToHomeworkCommons < ActiveRecord::Migration
def change
add_column :homework_commons, :simi_time, :datetime
end
end

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160325030423) do
ActiveRecord::Schema.define(:version => 20160330103916) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -809,6 +809,7 @@ ActiveRecord::Schema.define(:version => 20160325030423) do
t.integer "anonymous_comment", :default => 0
t.integer "quotes", :default => 0
t.integer "is_open", :default => 0
t.datetime "simi_time"
end
add_index "homework_commons", ["course_id", "id"], :name => "index_homework_commons_on_course_id_and_id"
@ -1683,6 +1684,8 @@ ActiveRecord::Schema.define(:version => 20160325030423) do
t.integer "absence_penalty", :default => 0
t.float "system_score", :default => 0.0
t.boolean "is_test", :default => false
t.integer "simi_id", :default => 0
t.integer "simi_value", :default => 0
end
add_index "student_works", ["homework_common_id", "user_id"], :name => "index_student_works_on_homework_common_id_and_user_id"

@ -395,6 +395,7 @@ Redmine::MenuManager.map :admin_menu do |menu|
menu.push :course_resource_list, {:controller => 'admin', :action => 'course_resource_list'}, :caption => :label_course_resource_list
menu.push :project_resource_list, {:controller => 'admin', :action => 'project_resource_list'}, :caption => :label_project_resource_list
menu.push :homework, {:controller => 'admin', :action => 'homework'}, :caption => :label_user_homework
menu.push :code_work_tests, {:controller => 'admin', :action => 'code_work_tests'}, :caption => :label_code_work_tests
end
#Modified by young

@ -0,0 +1,113 @@
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
position: relative;
background: #f8f8f8;
}
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
color: #555;
line-height: 1;
}
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
z-index: 3;
}
.CodeMirror-merge-copy-reverse {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
background: #eef;
border: 1px solid #ddf;
font-size: 90%;
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save