@ -6,16 +6,17 @@ class ShixunsController < ApplicationController
before_action :require_login , :check_auth , except : [ :download_file , :index , :menus , :show , :show_right , :ranking_list ,
before_action :require_login , :check_auth , except : [ :download_file , :index , :menus , :show , :show_right , :ranking_list ,
:discusses , :collaborators , :fork_list , :propaedeutics ]
:discusses , :collaborators , :fork_list , :propaedeutics ]
before_action :check_account , only : [ :new , :create , :shixun_exec ]
before_action :check_account , only : [ :new , :create , :shixun_exec , :jupyter_exec ]
before_action :find_shixun , except : [ :index , :new , :create , :menus , :get_recommend_shixuns ,
before_action :find_shixun , except : [ :index , :new , :create , :menus , :get_recommend_shixuns ,
:propaedeutics , :departments , :apply_shixun_mirror ,
:propaedeutics , :departments , :apply_shixun_mirror ,
:get_mirror_script , :download_file , :shixun_list , :batch_send_to_course ]
:get_mirror_script , :download_file , :shixun_list , :batch_send_to_course ]
before_action :shixun_access_allowed , except : [ :index , :new , :create , :menus , :get_recommend_shixuns ,
before_action :shixun_access_allowed , except : [ :index , :new , :create , :menus , :get_recommend_shixuns ,
:propaedeutics , :departments , :apply_shixun_mirror ,
:propaedeutics , :departments , :apply_shixun_mirror , :jupyter_exec ,
:get_mirror_script , :download_file , :shixun_list , :batch_send_to_course ]
:get_mirror_script , :download_file , :shixun_list , :batch_send_to_course ]
before_action :find_repo_name , only : [ :repository , :commits , :file_content , :update_file , :shixun_exec , :copy , :add_file ]
before_action :find_repo_name , only : [ :repository , :commits , :file_content , :update_file , :shixun_exec , :copy ,
:add_file , :jupyter_exec ]
before_action :allowed , only : [ :update , :close , :update_propaedeutics , :settings , :publish , :apply_public ,
before_action :allowed , only : [ :update , :close , :update_propaedeutics , :settings , :publish , :apply_public ,
:shixun_members_added , :change_manager , :collaborators_delete ,
:shixun_members_added , :change_manager , :collaborators_delete ,
@ -206,7 +207,7 @@ class ShixunsController < ApplicationController
@new_shixun = Shixun . new
@new_shixun = Shixun . new
@new_shixun . attributes = @shixun . attributes . dup . except ( " id " , " user_id " , " visits " , " gpid " , " status " , " identifier " , " averge_star " ,
@new_shixun . attributes = @shixun . attributes . dup . except ( " id " , " user_id " , " visits " , " gpid " , " status " , " identifier " , " averge_star " ,
" homepage_show " , " repo_name " , " myshixuns_count " , " challenges_count " ,
" homepage_show " , " repo_name " , " myshixuns_count " , " challenges_count " ,
" can_copy " , " created_at " , " updated_at " )
" can_copy " , " created_at " , " updated_at " , " public " )
@new_shixun . user_id = User . current . id
@new_shixun . user_id = User . current . id
@new_shixun . averge_star = 5
@new_shixun . averge_star = 5
@new_shixun . identifier = generate_identifier Shixun , 8
@new_shixun . identifier = generate_identifier Shixun , 8
@ -364,74 +365,162 @@ class ShixunsController < ApplicationController
end
end
def create
def create
# 评测脚本的一些操作
@shixun = CreateShixunService . call ( current_user , shixun_params , params )
main_type , sub_type = params [ :main_type ] , params [ :small_type ]
mirror = MirrorScript . where ( :mirror_repository_id = > main_type )
identifier = generate_identifier Shixun , 8
@shixun = Shixun . new ( shixun_params )
@shixun . identifier = identifier
@shixun . user_id = current_user . id
@shixun . reset_time , @shixun . modify_time = Time . now , Time . now
if sub_type . blank?
shixun_script = mirror . first . try ( :script )
else
main_mirror = MirrorRepository . find ( main_type ) . type_name
sub_mirror = MirrorRepository . where ( id : sub_type ) . pluck ( :type_name )
if main_mirror == " Java " && sub_mirror . include? ( " Mysql " )
shixun_script = mirror . last . try ( :script )
else
shixun_script = mirror . first . try ( :script )
shixun_script = modify_shixun_script @shixun , shixun_script
end
end
# 保存jupyter到版本库
def update_jupyter
jupyter_save_with_shixun ( @shixun , params [ :jupyter_port ] )
end
end
ActiveRecord :: Base . transaction do
def update
# 镜像方面
mirror_ids = MirrorRepository . where ( id : params [ :main_type ] )
. or ( MirrorRepository . where ( id : params [ :sub_type ] ) ) . pluck ( :id ) . uniq
old_mirror_ids = @shixun . shixun_mirror_repositories
. where ( mirror_repository_id : params [ :main_type ] )
. or ( @shixun . shixun_mirror_repositories . where ( mirror_repository_id : params [ :sub_type ] ) )
. pluck ( :mirror_repository_id ) . uniq
new_mirror_id = ( mirror_ids - old_mirror_ids ) . map { | id | { mirror_repository_id : id } } # 转换成数组hash方便操作
logger . info ( " # # # # # # # # # # new_mirror_id: #{ new_mirror_id } " )
logger . info ( " # # # # # # # # # # old_mirror_ids: #{ old_mirror_ids } " )
logger . info ( " # # # # # # # # # # mirror_ids: #{ mirror_ids } " )
# 服务配置方面
service_create_params = service_config_params [ :shixun_service_configs ]
. select { | config | ! old_mirror_ids . include? ( config [ :mirror_repository_id ] ) &&
MirrorRepository . find ( config [ :mirror_repository_id ] ) . name . present? }
service_update_params = service_config_params [ :shixun_service_configs ]
. select { | config | old_mirror_ids . include? ( config [ :mirror_repository_id ] ) }
logger . info ( " # # # # # # # # # service_create_params: #{ service_create_params } " )
logger . info ( " # # # # # # # # # service_update_params: #{ service_update_params } " )
begin
begin
@shixun . save!
ActiveRecord :: Base . transaction do
# shixun_info关联ß
@shixun . update_attributes ( shixun_params )
ShixunInfo . create! ( shixun_id : @shixun . id , evaluate_script : shixun_script , description : params [ :description ] )
@shixun . shixun_info . update_attributes ( shixun_info_params )
# 实训的公开范围
# 镜像变动
if params [ :scope_partment ] . present?
@shixun . shixun_mirror_repositories . where . not ( mirror_repository_id : old_mirror_ids ) . destroy_all
arr = [ ]
@shixun . shixun_mirror_repositories . create! ( new_mirror_id )
ids = School . where ( :name = > params [ :scope_partment ] ) . pluck ( :id ) . uniq
# 镜像变动要更换服务配置
ids . each do | id |
@shixun . shixun_service_configs . where . not ( mirror_repository_id : old_mirror_ids ) . destroy_all
arr << { :school_id = > id , :shixun_id = > @shixun . id }
@shixun . shixun_service_configs . create! ( service_create_params )
service_update_params & . map do | service |
smr = @shixun . shixun_service_configs . find_by ( mirror_repository_id : service [ :mirror_repository_id ] )
smr . update_attributes ( service )
end
# 添加第二仓库(管理员权限)
if params [ :is_secret_repository ]
add_secret_repository if @shixun . shixun_secret_repository . blank?
else
# 如果有仓库,就要删
if @shixun . shixun_secret_repository & . repo_name
@shixun . shixun_secret_repository . lock!
GitService . delete_repository ( repo_path : @shixun . shixun_secret_repository . repo_path )
@shixun . shixun_secret_repository . destroy
end
end
end
rescue = > e
uid_logger_error ( e . message )
tip_exception ( " 基本信息更新失败: #{ e . message } " )
end
end
ShixunSchool . create! ( arr )
end
end
# 实训合作者
# 实训权限设置
@shixun . shixun_members . create! ( user_id : current_user . id , role : 1 )
def update_permission_setting
# 查找需要增删的高校id
school_id = School . where ( :name = > params [ :scope_partment ] ) . pluck ( :id )
old_school_ids = @shixun . shixun_schools . pluck ( :school_id )
school_params = ( school_id - old_school_ids ) . map { | id | { school_id : id } }
begin
ActiveRecord :: Base . transaction do
@shixun . update_attributes! ( shixun_params )
@shixun . shixun_schools . where . not ( school_id : school_id ) . destroy_all if school_id . present?
@shixun . shixun_schools . create! ( school_params )
end
rescue = > e
uid_logger_error ( " 实训权限设置失败-------- #{ e . message } " )
tip_exception ( " 实训权限设置失败 " )
end
end
# 镜像-实训关联表
# 实训学习页面设置
ShixunMirrorRepository . create! ( :shixun_id = > @shixun . id , :mirror_repository_id = > main_type . to_i ) if main_type . present?
def update_learn_setting
# 实训主镜像服务配置
begin
ShixunServiceConfig . create! ( :shixun_id = > @shixun . id , :mirror_repository_id = > main_type . to_i )
ActiveRecord :: Base . transaction do
if sub_type . present?
@shixun . update_attributes! ( shixun_params )
sub_type . each do | mirror |
end
ShixunMirrorRepository . create! ( :shixun_id = > @shixun . id , :mirror_repository_id = > mirror )
rescue = > e
# 实训子镜像服务配置
uid_logger_error ( " 实训学习页面设置失败-------- #{ e . message } " )
name = MirrorRepository . find_by ( id : mirror ) . try ( :name ) #查看镜像是否有名称,如果没有名称就不用服务配置
tip_exception ( " 实训学习页面设置失败 " )
ShixunServiceConfig . create! ( :shixun_id = > @shixun . id , :mirror_repository_id = > mirror ) if name . present?
end
end
end
end
# 创建版本库
# Jupyter数据集
repo_path = repo_namespace ( User . current . login , @shixun . identifier )
def get_data_sets
GitService . add_repository ( repo_path : repo_path )
page = params [ :page ] || 1
# todo: 为什么保存的时候要去除后面的.git呢??
limit = params [ :limit ] || 10
@shixun . update_column ( :repo_name , repo_path . split ( " . " ) [ 0 ] )
data_sets = @shixun . data_sets
@data_count = data_sets . count
@data_sets = data_sets . order ( " created_on desc " ) . page ( page ) . per ( limit )
@absolute_folder = edu_setting ( 'shixun_folder' )
end
# 将实训标志为该云上实验室建立
# 实训测试集附件
Laboratory . current . laboratory_shixuns . create! ( shixun : @shixun , ownership : true )
def upload_data_sets
rescue Exception = > e
begin
upload_file = params [ " file " ]
raise " 未上传文件 " unless upload_file
folder = edu_setting ( 'shixun_folder' )
raise " 存储目录未定义 " unless folder . present?
rep_name = @shixun . data_sets . pluck ( :filename ) . include? ( upload_file . original_filename )
raise " 文件名已经存在 \" #{ upload_file . original_filename } \" , 请删除后再上传 " if rep_name
tpm_folder = params [ :identifier ] # 这个是实训的identifier
save_path = File . join ( folder , tpm_folder )
ext = file_ext ( upload_file . original_filename )
local_path , digest = file_save_to_local ( save_path , upload_file . tempfile , ext )
content_type = upload_file . content_type . presence || 'application/octet-stream'
disk_filename = local_path [ save_path . size + 1 , local_path . size ]
@attachment = Attachment . where ( disk_filename : disk_filename ,
author_id : current_user . id ) . first
if @attachment . blank?
@attachment = Attachment . new
@attachment . filename = upload_file . original_filename
@attachment . disk_filename = local_path [ save_path . size + 1 , local_path . size ]
@attachment . filesize = upload_file . tempfile . size
@attachment . content_type = content_type
@attachment . digest = digest
@attachment . author_id = current_user . id
@attachment . disk_directory = tpm_folder
@attachment . container_id = @shixun . id
@attachment . container_type = @shixun . class . name
@attachment . attachtype = 2
@attachment . save!
else
logger . info " 文件已存在, id = #{ @attachment . id } , filename = #{ @attachment . filename } "
end
render_ok
rescue = > e
uid_logger_error ( e . message )
uid_logger_error ( e . message )
tip_exception ( " 实训创建失败 " )
tip_exception ( e . message )
raise ActiveRecord :: Rollback
end
end
end
end
# 多文件删除
def destroy_data_sets
files = Attachment . where ( id : params [ :id ] )
shixun_folder = edu_setting ( " shixun_folder " )
begin
files . each do | file |
file_path = " #{ shixun_folder } / #{ file . relative_path_filename } "
delete_file ( file_path )
end
files . destroy_all
render_ok
rescue = > e
uid_logger_error ( e . message )
tip_exception ( e . message )
end
end
end
def apply_shixun_mirror
def apply_shixun_mirror
@ -462,61 +551,6 @@ class ShixunsController < ApplicationController
tip_exception ( " 申请失败 " )
tip_exception ( " 申请失败 " )
end
end
def update
ActiveRecord :: Base . transaction do
begin
@shixun . shixun_mirror_repositories . destroy_all
if params [ :main_type ] . present?
ShixunMirrorRepository . create ( :shixun_id = > @shixun . id , :mirror_repository_id = > params [ :main_type ] . to_i )
end
if params [ :small_type ] . present?
params [ :small_type ] . each do | mirror |
ShixunMirrorRepository . create ( :shixun_id = > @shixun . id , :mirror_repository_id = > mirror )
end
end
@shixun . update_attributes ( shixun_params )
@shixun . shixun_info . update_attributes ( shixun_info_params )
@shixun . shixun_schools . delete_all
# scope_partment: 高校的名称
if params [ :scope_partment ] . present?
arr = [ ]
ids = School . where ( :name = > params [ :scope_partment ] ) . pluck ( :id ) . uniq
ids . each do | id |
arr << { :school_id = > id , :shixun_id = > @shixun . id }
end
ShixunSchool . create! ( arr )
end
# 超级管理员和运营人员才能保存 中间层服务器pod信息的配置
# 如果镜像改动了,则也需要更改
mirror = @shixun . shixun_service_configs . map ( & :mirror_repository_id ) . sort
new_mirror = params [ :shixun_service_configs ] . map { | c | c [ :mirror_repository_id ] } . sort
if current_user . admin? || current_user . business? || ( mirror != new_mirror )
@shixun . shixun_service_configs . destroy_all
service_config_params [ :shixun_service_configs ] . each do | config |
name = MirrorRepository . find_by_id ( config [ :mirror_repository_id ] ) & . name
# 不保存没有镜像的配置
@shixun . shixun_service_configs . create! ( config ) if name . present?
end
end
# 添加第二仓库
if params [ :is_secret_repository ]
add_secret_repository if @shixun . shixun_secret_repository . blank?
else
# 如果有仓库,就要删
if @shixun . shixun_secret_repository & . repo_name
@shixun . shixun_secret_repository . lock!
GitService . delete_repository ( repo_path : @shixun . shixun_secret_repository . repo_path )
@shixun . shixun_secret_repository . destroy
end
end
rescue Exception = > e
uid_logger_error ( " 实训保存失败-------- #{ e . message } " )
tip_exception ( " 实训保存失败 " )
raise ActiveRecord :: Rollback
end
end
end
# 永久关闭实训
# 永久关闭实训
def close
def close
@ -552,6 +586,8 @@ class ShixunsController < ApplicationController
# @evaluate_scirpt = @shixun.evaluate_script || "无"
# @evaluate_scirpt = @shixun.evaluate_script || "无"
end
end
# 获取脚本内容
# 获取脚本内容
def get_script_contents
def get_script_contents
mirrir_script = MirrorScript . find ( params [ :script_id ] )
mirrir_script = MirrorScript . find ( params [ :script_id ] )
@ -708,112 +744,40 @@ class ShixunsController < ApplicationController
end
end
end
end
# def shixun_exec
# jupyter开启挑战
# if is_shixun_opening?
def jupyter_exec
# tip_show_exception(-3, "#{@shixun.opening_time.strftime('%Y-%m-%d %H:%M:%S')}")
begin
# end
if is_shixun_opening?
# current_myshixun = @shixun.current_myshixun(current_user.id)
tip_show_exception ( - 3 , " #{ @shixun . opening_time . strftime ( '%Y-%m-%d %H:%M:%S' ) } " )
#
end
# min_challenges = @shixun.challenges.pluck(:id , :st)
current_myshixun = @shixun . current_myshixun ( current_user . id )
# # 因为读写分离有延迟, 所以如果是重置来的请求可以先跳过, 重置过来的params[:reset]为1
if current_myshixun
# if current_myshixun && params[:reset] != "1"
@myshixun = current_myshixun
# games = current_myshixun.games
else
# # 如果TPM和TPI的管卡数不相等或者关卡顺序错了, 说明实训被极大的改动, 需要重置,实训发布前打过的实训都需要重置
commit = GitService . commits ( repo_path : @repo_path ) . try ( :first )
# if is_shixun_reset?(games, min_challenges, current_myshixun)
uid_logger ( " First comit # # # # # # # #{ commit } " )
# # 这里页面弹框要收到 当前用户myshixun的identifier.
tip_exception ( " 开启挑战前, 请先在Jupyter中填写内容 " ) if commit . blank?
# tip_show_exception("/myshixuns/#{current_myshixun.try(:identifier)}/reset_my_game")
commit_id = commit [ " id " ]
# end
cloud_bridge = edu_setting ( 'cloud_bridge' )
#
myshixun_identifier = generate_identifier Myshixun , 10
#
ActiveRecord :: Base . transaction do
# if current_myshixun.repo_name.nil?
@myshixun = @shixun . myshixuns . create! ( user_id : current_user . id , identifier : myshixun_identifier ,
# g = Gitlab.client
modify_time : @shixun . modify_time , reset_time : @shixun . reset_time ,
# repo_name = g.project(current_myshixun.gpid).try(:path_with_namespace)
onclick_time : Time . now , commit_id : commit_id )
# current_myshixun.update_column(:repo_name, repo_name)
# fork仓库
# end
project_fork ( @myshixun , @repo_path , current_user . login )
#
rep_url = Base64 . urlsafe_encode64 ( repo_ip_url @repo_path )
# # 如果存在实训,则直接进入实训
uri = " #{ cloud_bridge } /bridge/game/openGameInstance "
# # 如果实训允许跳关, 传参params[:challenge_id]跳入具体的关卡
params = { tpiID : " #{ @myshixun . id } " , tpmGitURL : rep_url , tpiRepoName : @myshixun . repo_name . split ( " / " ) . last }
# @current_task =
interface_post uri , params , 83 , " 实训云平台繁忙( 繁忙等级: 83) "
# if params[:challenge_id]
end
# game = games.where(challenge_id: params[:challenge_id]).take
end
# if @shixun.task_pass || game.status != 3
rescue = > e
# game
uid_logger_error ( e . message )
# else
tip_exception ( " #{ e . message } " )
# current_myshixun.current_task(games)
end
# end
end
# else
# current_myshixun.current_task(games)
# end
# else
# # 如果未创建关卡一定不能开启实训, 否则TPI没法找到当前的关卡
# if @shixun.challenges_count == 0
# tip_exception("开启实战前请先创建实训关卡")
# end
#
# # 判断实训是否全为选择题
# is_choice_type = (min_challenges.size == min_challenges.select{|challenge| challenge.last == 1}.count)
# if !is_choice_type
# commit = GitService.commits(repo_path: @repo_path).try(:first)
# uid_logger("First comit########{commit}")
# tip_exception("开启实战前请先在版本库中提交代码") if commit.blank?
# commit_id = commit["id"]
# end
#
# begin
# ActiveRecord::Base.transaction do
# begin
# myshixun_identifier = generate_identifier Myshixun, 10
# myshixun_params = {user_id: current_user.id, identifier: myshixun_identifier,
# modify_time: @shixun.modify_time, reset_time: @shixun.reset_time,
# onclick_time: Time.now, commit_id: commit_id}
# @myshixun = @shixun.myshixuns.create!(myshixun_params)
# # 其它创建关卡等操作
# challenges = @shixun.challenges
# # 之所以增加user_id是为了方便统计查询性能
# game_attrs = %i[challenge_id myshixun_id status user_id open_time identifier modify_time created_at updated_at]
# Game.bulk_insert(*game_attrs) do |worker|
# base_attr = {myshixun_id: @myshixun.id, user_id: @myshixun.user_id}
# challenges.each_with_index do |challenge, index|
# status = (index == 0 ? 0 : 3)
# game_identifier = generate_identifier(Game, 12)
# worker.add(base_attr.merge(challenge_id: challenge.id, status: status, open_time: Time.now,
# identifier: game_identifier, modify_time: challenge.modify_time))
# end
# end
# @current_task = @myshixun.current_task(@myshixun.games)
# rescue Exception => e
# logger.error("------ActiveRecord::RecordInvalid: #{e.message}")
# raise("ActiveRecord::RecordInvalid")
# end
# end
# # 如果实训是纯选择题, 则不需要去fork仓库以及中间层的相关操作了
# ActiveRecord::Base.transaction do
# unless is_choice_type
# # fork仓库
# cloud_bridge = edu_setting('cloud_bridge')
# project_fork(@myshixun, @repo_path, current_user.login)
# rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path)
# uid_logger("start openGameInstance")
# uri = "#{cloud_bridge}/bridge/game/openGameInstance"
# logger.info("end openGameInstance")
# params = {tpiID: "#{@myshixun.id}", tpmGitURL: rep_url, tpiRepoName: @myshixun.repo_name.split("/").last}
# uid_logger("openGameInstance params is #{params}")
# interface_post uri, params, 83, "实训云平台繁忙( 繁忙等级: 83) "
# end
# end
# rescue Exception => e
# logger.info("shixun_exec error: #{e.message}")
# if e.message != "ActiveRecord::RecordInvalid"
# logger.error("##########project_fork error #{e.message}")
# @myshixun.destroy!
# end
# raise "实训云平台繁忙( 繁忙等级: 81) "
# end
# end
# end
# gameID 及实训ID
# status: 0 , 1 申请过, 2, 实训关卡路径未填, 3 实训标签未填, 4 实训未创建关卡
def publish
def publish
@status = 0
@status = 0
@position = [ ]
@position = [ ]
@ -849,7 +813,7 @@ class ShixunsController < ApplicationController
def apply_public
def apply_public
tip_exception ( - 1 , " 请先发布实训再申请公开 " ) if @shixun . status != 2
tip_exception ( - 1 , " 请先发布实训再申请公开 " ) if @shixun . status != 2
ActiveRecord :: Base . transaction do
ActiveRecord :: Base . transaction do
@shixun . update_attributes! ( pub ic: 1 )
@shixun . update_attributes! ( publ ic: 1 )
apply = ApplyAction . where ( :container_type = > " ApplyShixun " , :container_id = > @shixun . id ) . order ( " created_at desc " ) . first
apply = ApplyAction . where ( :container_type = > " ApplyShixun " , :container_id = > @shixun . id ) . order ( " created_at desc " ) . first
if apply && apply . status == 0
if apply && apply . status == 0
@status = 0
@status = 0
@ -1035,10 +999,9 @@ class ShixunsController < ApplicationController
private
private
def shixun_params
def shixun_params
raise ( " 实训名称不能为空 " ) if params [ :shixun ] [ :name ] . blank?
params . require ( :shixun ) . permit ( :name , :trainee , :webssh , :can_copy , :use_scope , :vnc , :test_set_permission ,
params . require ( :shixun ) . permit ( :name , :trainee , :webssh , :can_copy , :use_scope , :vnc , :test_set_permission ,
:task_pass , :multi_webssh , :opening_time , :mirror_script_id , :code_hidden ,
:task_pass , :multi_webssh , :opening_time , :mirror_script_id , :code_hidden ,
:hide_code , :forbid_copy , :vnc_evaluate , :code_edit_permission )
:hide_code , :forbid_copy , :vnc_evaluate , :code_edit_permission , :is_jupyter )
end
end
def validate_review_shixun_params
def validate_review_shixun_params
@ -1047,8 +1010,6 @@ private
end
end
def shixun_info_params
def shixun_info_params
raise ( " 实训描述不能为空 " ) if params [ :shixun_info ] [ :description ] . blank?
raise ( " 评测脚本不能为空 " ) if params [ :shixun_info ] [ :evaluate_script ] . blank?
params . require ( :shixun_info ) . permit ( :description , :evaluate_script )
params . require ( :shixun_info ) . permit ( :description , :evaluate_script )
end
end
@ -1116,4 +1077,47 @@ private
ShixunSecretRepository . create! ( repo_name : repo_path . split ( " . " ) [ 0 ] , shixun_id : @shixun . id )
ShixunSecretRepository . create! ( repo_name : repo_path . split ( " . " ) [ 0 ] , shixun_id : @shixun . id )
end
end
def file_save_to_local ( save_path , temp_file , ext )
unless Dir . exists? ( save_path )
FileUtils . mkdir_p ( save_path ) ##不成功这里会抛异常
end
digest = md5_file ( temp_file )
digest = " #{ digest } _ #{ ( Time . now . to_f * 1000 ) . to_i } "
local_file_path = File . join ( save_path , digest ) + ext
save_temp_file ( temp_file , local_file_path )
[ local_file_path , digest ]
end
def save_temp_file ( temp_file , save_file_path )
File . open ( save_file_path , 'wb' ) do | f |
temp_file . rewind
while ( buffer = temp_file . read ( 8192 ) )
f . write ( buffer )
end
end
end
def file_ext ( file_name )
ext = ''
exts = file_name . split ( " . " )
if exts . size > 1
ext = " . #{ exts . last } "
end
ext
end
def delete_file ( file_path )
File . delete ( file_path ) if File . exist? ( file_path )
end
def md5_file ( temp_file )
md5 = Digest :: MD5 . new
temp_file . rewind
while ( buffer = temp_file . read ( 8192 ) )
md5 . update ( buffer )
end
md5 . hexdigest
end
end
end