init project

This commit is contained in:
Jasder
2020-03-09 00:40:16 +08:00
commit 2937b2a94d
6549 changed files with 7215173 additions and 0 deletions

View File

View File

@@ -0,0 +1,18 @@
module Admins::RenderHelper
extend ActiveSupport::Concern
include Base::RenderHelper
def render_delete_success
render_js_template 'admins/shared/delete'
end
alias_method :render_success_js, :render_delete_success
def render_js_error(message, type: :alert)
if type == :notify
render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });"
else
render_js_template 'admins/shared/error', locals: { message: message }
end
end
end

View File

@@ -0,0 +1,25 @@
module Base::ErrorRescueHandler
extend ActiveSupport::Concern
included do
rescue_from Exception do |e|
raise e if Rails.env.development?
Util.logger_error e
internal_server_error
end
rescue_from ActionView::MissingTemplate, ActiveRecord::RecordNotFound, with: :render_not_found
rescue_from ActionController::ParameterMissing do
render_unprocessable_entity('参数缺失')
end
# form validation error
rescue_from ActiveModel::ValidationError do |ex|
render_unprocessable_entity(ex.model.errors.full_messages.join(','))
end
rescue_from ActiveRecord::RecordInvalid do |ex|
ex.backtrace.each { |msg| Rails.logger.error(msg) }
render_unprocessable_entity(ex.record.errors.full_messages.join(','))
end
end
end

View File

@@ -0,0 +1,29 @@
module Base::PaginateHelper
extend ActiveSupport::Concern
def default_sort(sort_by, direction)
params[:sort_by] = params[:sort_by].presence || sort_by
params[:sort_direction] = params[:sort_direction].presence || direction
end
def offset
(page - 1) * per_page
end
def page
params[:page].to_i <= 0 ? 1 : params[:page].to_i
end
def per_page
params[:per_page].to_i <= 0 || params[:per_page].to_i > 100 ? 20 : params[:per_page].to_i
end
alias_method :limit, :per_page
def paginate(relations, total_count: nil)
if relations.is_a?(Array)
Kaminari.paginate_array(relations, limit: limit, offset: offset, total_count: total_count)
else
relations.page(page).per(per_page)
end
end
end

View File

@@ -0,0 +1,38 @@
module Base::RenderHelper
extend ActiveSupport::Concern
def render_by_format(hash)
format = request.format.symbol
hash.key?(format) ? hash[format].call : hash[:html].call
end
def render_forbidden
render_by_format(html: -> { current_user&.business? ? render('shared/403') : redirect_to('/403') },
js: -> { render_js_error(I18n.t('error.forbidden'), type: :notify) },
json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
end
def render_not_found
render_by_format(html: -> { render 'shared/404' },
js: -> { render_js_error('资源未找到') },
json: -> { render status: 404, json: { message: '资源未找到' } })
end
def render_unprocessable_entity(message, type: :alert)
render_by_format(html: -> { render 'shared/422' },
js: -> { render_js_error(message, type: type) },
json: -> { render status: 422, json: { message: message } })
end
alias_method :render_error, :render_unprocessable_entity
def internal_server_error(message = '系统错误')
@message = message
render_by_format(html: -> { render 'shared/500' },
js: -> { render_js_error(message) },
json: -> { render status: 500, json: { message: message } })
end
def render_js_template(template, **opts)
render({ template: template, formats: :js }.merge(opts))
end
end

View File

@@ -0,0 +1,137 @@
module CodeExample
extend ActiveSupport::Concern
#老师C语言的标准代码
def c_stantard_code_teacher
"// 老师您好这是一个C语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <stdio.h> //引用必须头文件
int main(int argc, char** argv) {
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
printf(\"%d\",a+b); //输出a+b
return 0;
}".html_safe
end
#老师C++语言的标准代码
def c_stantard_code_teacher_
"// 老师您好这是一个C++语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
#学生C语言的标准代码
def c_stantard_code_student
"// 同学好这是一个C语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <stdio.h> //引用必须头文件
int main(int argc, char** argv) {
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
printf(\"%d\",a+b); //输出a+b
return 0;
}".html_safe
end
#学生C++语言的标准代码
def c_stantard_code_student_
"// 同学好这是一个C++语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
def compile_command
"compile(){
# 编译命令
compileCommand=\"COMPILECOMMAND\"
# 取当前关卡的编译文件
challengeProgramName=${challengeProgramNames[$1 - 1]}
# 获取编译结果(此处编译无输出则说明编译通过,否则输出编译错误信息,请按实训实际情况调整)
compileResult=$($compileCommand $challengeProgramName 2>&1 | base64)
if [ -z \"$compileResult\" ]; then
compileResult=$(echo -n \"compile successfully\" | base64)
fi
}
compile $1"
end
def execute_command
"execute(){
#执行命令
executeCommand=\"EXECUTECOMMAND\"
#执行文件名
sourceClassName=${sourceClassNames[$1 - 1]}
challengeStage=$1
output=''
i=0
while [[ i -lt ${#ins[*]} ]]; do
#执行,并拼接执行结果
result=$(echo \"${ins[$i]}\" | base64 -d | $executeCommand $sourceClassName 2>&1 | base64)
#拼接输出结果
output=$output\\\"$result\\\",
let i++
done
output=\"[${output%?}]\"
}
execute $1
"
end
end

View File

@@ -0,0 +1,40 @@
module ControllerRescueHandler
extend ActiveSupport::Concern
included do
rescue_from Exception do |e|
Util.logger_error e
render json: {status: -1, message: e.message}
end
rescue_from ActiveRecord::StatementInvalid do |e|
Util.logger_error e
render json: {status: -1, message: "接口数据异常"}
end
rescue_from NoMethodError do |e|
Util.logger_error e
render json: {status: -1, message: "接口方法异常"}
end
rescue_from ActionController::UnknownFormat do |e|
render json: {status: -1, message: "接口调用非JSON格式"}
end
# rescue_from ActionView::MissingTemplate, with: :object_not_found
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from Educoder::TipException, with: :tip_show
rescue_from ::ActionView::MissingTemplate, with: :missing_template
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing
# form validation error
rescue_from ActiveModel::ValidationError do |ex|
render_error(ex.model.errors.full_messages.join(','))
end
rescue_from ActiveRecord::RecordInvalid do |ex|
render_error(ex.record.errors.full_messages.join(','))
end
# rescue_from RuntimeError do |ex|
# Util.logger_error "#######ex:#{ex}"
# render_error(ex.message)
# end
end
end

View File

@@ -0,0 +1,16 @@
module Cooperative::RenderHelper
include Base::RenderHelper
def render_delete_success
render_js_template 'cooperative/shared/delete'
end
alias_method :render_success_js, :render_delete_success
def render_js_error(message, type: :alert)
if type == :notify
render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });"
else
render_js_template 'cooperative/shared/error', locals: { message: message }
end
end
end

View File

@@ -0,0 +1,59 @@
module GitCommon
extend ActiveSupport::Concern
included do
end
# ------------------------
# 版本库目录结构
def repository
begin
@repo_url = repo_url @repo_path
@trees = GitService.file_tree(repo_path: @repo_path, path: @path)
logger.info("#11@@#@#@#@111#@@@@###{@trees}")
# TPI(学员实训)不需要获取最近的一次提交
if params[:controller] != "myshixuns" && @trees
logger.info("#@@#@#@#@#@@@@###{@trees.try(:count)}")
@latest_commit = [GitService.commits(repo_path: @repo_path).first]
Rails.logger.info("########## #{@latest_commit}")
end
rescue Exception => e
logger.error(e.message)
end
end
def file_content
@content = git_fle_content @repo_path, @path
end
# 版本库提交记录
# Redo: commit接口需要按倒叙排列
def commits
begin
@commits = GitService.commits(repo_path: @repo_path)
logger.info("git first commit is #{@commits.try(:first)}")
raise Educoder::TipException.new("请先创建版本库") if @commits.nil?
rescue Exception => e
uid_logger_error(e.message)
raise Educoder::TipException.new("提交记录异常")
end
end
# 为版本库添加文件
def add_file
@path, message, content = params[:path].strip, params[:message], params[:content]
author_name, author_email = current_user.real_name, current_user.git_mail
Rails.logger.info(" good repo_name is #{@repo_path}")
@content = GitService.update_file(repo_path: @repo_path,
file_path: @path,
message: message.force_encoding('UTF-8'),
content: content.force_encoding('UTF-8'),
author_name: author_name,
author_email: author_email)
end
end

View File

@@ -0,0 +1,80 @@
module GitHelper
extend ActiveSupport::Concern
# 版本库目录空间
def repo_namespace(user_login, shixun_identifier)
"#{user_login}/#{shixun_identifier}.git"
end
# 版本库文件内容,带转码
def git_fle_content(repo_path, path)
begin
Rails.logger.info("git file content: repo_path is #{repo_path}, path is #{path}")
content = GitService.file_content(repo_path: repo_path, path: path)
Rails.logger.info("git file content: content is #{content}")
decode_content = nil
if content.present?
content = content["content"] #6.24 -hs 这个为新增,因为当实训题里含有选择题时,这里会报错,undefined method `[]' for nil:NilClass
content = Base64.decode64(content)
cd = CharDet.detect(content)
Rails.logger.info "encoding: #{cd['encoding']} confidence: #{cd['confidence']}"
# 字符编码问题GB18030编码识别率不行
decode_content =
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
else
content.force_encoding('UTF-8')
end
end
decode_content
rescue Exception => e
Rails.logger.error(e.message)
raise Educoder::TipException.new("文档内容获取异常")
end
end
# 更新文件代码
# content 文件内容message提交描述
def update_file_content(content, repo_path, path, mail, username, message)
#content = Base64.encode64(content)
GitService.update_file(repo_path: repo_path, file_path: path, message: message,
content: content, author_name: username, author_email: mail)
end
def update_file_base64_content(content, repo_path, path, mail, username, message)
content = Base64.encode64(content)
GitService.update_file_base64(repo_path: repo_path, file_path: path, message: message,
content: content, author_name: username, author_email: mail)
end
# 添加目录
def git_add_folder(folder_path, author_name, author_email, message)
GitService.add_tree(file_path: folder_path, message: message, author_name: author_name, author_email: author_email)
end
# 删除文件
def git_delete_file(file_path, author_name, author_email, message)
GitService.delete_file(file_path: file_path, message: message, author_name: author_name, author_email: author_email)
end
# 版本库Fork功能
def project_fork(container, original_rep_path, username)
raise Educoder::TipException.new("fork源路径为空,fork失败!") if original_rep_path.blank?
# 将要生成的仓库名字
new_repo_name = "#{username.try(:strip)}/#{container.try(:identifier)}#{ Time.now.strftime("%Y%m%d%H%M%S")}"
# uid_logger("start fork container: repo_name is #{new_repo_name}")
GitService.fork_repository(repo_path: original_rep_path, fork_repository_path: (new_repo_name + ".git"))
container.update_attributes!(:repo_name => new_repo_name)
end
#实训题的关卡url初始化
def challenge_path(path)
cha_path = path.present? ? path.split("") : []
cha_path.reject(&:blank?)[0].try(:strip)
end
end

View File

@@ -0,0 +1,32 @@
module LaboratoryHelper
extend ActiveSupport::Concern
included do
before_action :setup_laboratory
helper_method :current_laboratory
helper_method :default_setting
helper_method :default_yun_session
end
def current_laboratory
@_current_laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
end
def default_laboratory
@_default_laboratory ||= Laboratory.find(1)
end
def default_setting
@_default_setting ||= LaboratorySetting.find_by(laboratory_id: 1)
end
def setup_laboratory
Laboratory.current = current_laboratory
end
def default_yun_session
laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
@_default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id"
end
end

View File

@@ -0,0 +1,22 @@
module LoggerHelper
extend ActiveSupport::Concern
extend LoggerHelper
# 以用户id开始的日志定义
def uid_logger(message)
Rails.logger.info("##:#{current_user.try(:id)} --#{message}")
end
# debug日志
def uid_logger_dubug(message)
Rails.logger.info("##dubug-#{current_user.try(:id)} --#{message}")
end
# 以用户id开始的日志定义
def uid_logger_error(message)
Rails.logger.error("##:#{current_user.try(:id)} --#{message}")
end
end

View File

@@ -0,0 +1,85 @@
module LoginHelper
extend ActiveSupport::Concern
def edu_setting(name)
EduSetting.get(name)
end
def autologin_cookie_name
edu_setting('autologin_cookie_name').presence || 'autologin'
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin")
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => '/',
:secure => false,
:httponly => false
}
if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
end
cookies[autologin_cookie_name] = cookie_options
Rails.logger.info("cookies is #{cookies}")
end
def successful_authentication(user)
Rails.logger.info("id: #{user&.id} Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
# Valid user
self.logged_user = user
session[:"#{default_yun_session}"] = user.id
# generate a key and set cookie if autologin
set_autologin_cookie(user)
UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip)
user.update_column(:last_login_on, Time.now)
# 注册完成后有一天的试用申请(先去掉)
# UserDayCertification.create(user_id: user.id, status: 1)
end
def logout_user
if User.current.logged?
if autologin = cookies.delete(autologin_cookie_name)
User.current.delete_autologin_token(autologin)
end
User.current.delete_session_token(session[:tk])
self.logged_user = nil
end
# 云上实验室退出清理当前session
laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id"
# end
session[:"#{default_yun_session}"] = nil
end
# Sets the logged in user
def logged_user=(user)
# reset_session
if user && user.is_a?(User)
User.current = user
start_user_session(user)
else
User.current = User.anonymous
end
end
def start_user_session(user)
# re_subdomain = "#{request.subdomain.split('.').first}_user_id"
# session[:"#{request.subdomain}_user_id"] = user.id
# Rails.logger.info("domain_user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}")
# Rails.logger.info("user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}")
#
# # if current_laboratory.main_site?
# # session[:user_id] = user.id
# # else
# # session[:"#{request.subdomain}_user_id"] = user.id
# # end
# session[:user_id] = user.id
session[:"#{default_yun_session}"] = user.id
session[:ctime] = Time.now.utc.to_i
session[:atime] = Time.now.utc.to_i
end
end

View File

@@ -0,0 +1,12 @@
module OperateProjectAbilityAble
extend ActiveSupport::Concern
included do
end
def authorizate_user_can_edit_project!
return if current_user.project_manager? @project || current_user.admin?
render_forbidden('你没有权限操作.')
end
end

View File

@@ -0,0 +1,12 @@
module PaginateHelper
def paginate(objs, **opts)
page = params[:page].to_i <= 0 ? 1 : params[:page].to_i
per_page = params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : opts[:per_page] || 20
if objs.is_a?(Array)
Kaminari.paginate_array(objs).page(page).per(per_page)
else
objs.page(page).per(per_page)
end
end
end

View File

@@ -0,0 +1,40 @@
module RenderExpand
extend ActiveSupport::Concern
included do
ActionController.add_renderer :pdf do |template, options|
file = File.open(Rails.root.join('app/templates', template << '.html.erb'))
html = ERB.new(file.read).result(binding)
kit = PDFKit.new(html)
base_css = %w(app/templates/shared/main.css)
base_css.each { |css| kit.stylesheets << Rails.root.join(css) }
Array.wrap(options.delete(:stylesheets)).each do |path|
kit.stylesheets << Rails.root.join('app/templates', path)
end
send_data kit.to_pdf, filename: options[:filename], disposition: options[:disposition] || 'attachment', type: 'application/pdf'
end
ActionController.add_renderer :exam_pdf do |template, options|
file = File.open(Rails.root.join('app/templates', template << '.html.erb'))
html = ERB.new(file.read).result(binding)
kit = PDFKit.new(html)
# PDFKit初始化后再添加样式文件到stylesheets会出现在页面的<!DOCTYPE>定义不起作用文档模式为默认为BackCompat从而导致katex不起作用
# 而测试发现通过配置添加css样式文件不会有影响
PDFKit.configure do |config|
config.default_options = {
:"user-style-sheet" => Rails.root.join('app/templates', options[:stylesheets])
}
end
send_data kit.to_pdf, filename: options[:filename], disposition: options[:disposition] || 'attachment', type: 'application/pdf'
end
end
end

View File

@@ -0,0 +1,31 @@
module RenderHelper
def render_ok(data = {})
render json: { status: 0, message: 'success' }.merge(data)
end
def render_error(message = '')
render json: { status: -1, message: message }
end
def render_not_acceptable(message = '请求已拒绝')
render json: { status: 406, message: message }
end
def render_not_found(message = I18n.t('error.record_not_found'))
render json: { status: 404, message: message }
# render status: 404, json: { errors: errors }
end
def render_forbidden(message = I18n.t('error.forbidden'))
render json: { status: 403, message: message }
# render status: 403, json: { errors: errors }
end
def render_unauthorized(message = I18n.t('error.unauthorized'))
render json: { status: 401, message: message }
end
def render_result(status=1, message='success')
render json: { status: status, message: message }
end
end