137 lines
4.6 KiB
Ruby
137 lines
4.6 KiB
Ruby
require 'zip'
|
||
class ZipdownController < ApplicationController
|
||
#查找项目(课程)
|
||
before_filter :find_project_by_bid_id, :only => [:assort]
|
||
#检查权限
|
||
#勿删 before_filter :authorize, :only => [:assort,:download_user_homework]
|
||
SAVE_FOLDER = "#{Rails.root}/files"
|
||
OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip"
|
||
|
||
#通过作业Id找到项目(课程)
|
||
def find_project_by_bid_id
|
||
obj_class = params[:obj_class]
|
||
obj_id = params[:obj_id]
|
||
obj = obj_class.constantize.find(obj_id)
|
||
case obj.class.to_s.to_sym
|
||
when :Bid
|
||
@project = obj.courses[0]
|
||
end
|
||
end
|
||
|
||
def assort
|
||
obj_class = params[:obj_class]
|
||
obj_id = params[:obj_id]
|
||
obj = obj_class.constantize.find(obj_id)
|
||
zipfile = nil
|
||
case obj.class.to_s.to_sym
|
||
when :Bid
|
||
zipfile = zip_bid obj
|
||
else
|
||
logger.error "[ZipDown#assort] ===> #{obj.class.to_s.to_sym} unKown !!"
|
||
end
|
||
send_file zipfile, :filename => obj.name+".zip", :type => detect_content_type(zipfile) if zipfile
|
||
|
||
rescue Exception => e
|
||
render file: 'public/no_file_found.html'
|
||
end
|
||
|
||
#下载某一学生的作业的所有文件
|
||
def download_user_homework
|
||
homework = HomeworkAttach.find params[:homework]
|
||
if User.current.admin? || User.current.member_of_course?(homework.bid.courses.first)
|
||
if homework != nil
|
||
if homework.attachments.count > 0
|
||
zipfile = zip_homework_by_user homework
|
||
send_file zipfile, :filename => homework.name+".zip", :type => detect_content_type(zipfile) if(zipfile)
|
||
else
|
||
render file: 'public/no_file_found.html' , :layout => 'course_base'
|
||
end
|
||
else
|
||
render file: 'public/file_not_found.html' , :layout => 'course_base'
|
||
end
|
||
else
|
||
render_403 :message => :notice_not_authorized ,:layout => "course_base"
|
||
end
|
||
rescue => e
|
||
render file: 'public/file_not_found.html' , :layout => 'course_base'
|
||
end
|
||
|
||
private
|
||
|
||
def zip_user_bid(bid,user_id)
|
||
# Todo: User Access Controll
|
||
|
||
homeattaches = bid.homeworks.where("user_id = ?",user_id)
|
||
# 得到每一个人所有文件打包的zip文件
|
||
# 并将每一个人的zip打包为一个并返回路径
|
||
user_zip_paths = homeattaches.map do |homeattach|
|
||
zip_homework_by_user homeattach
|
||
end
|
||
user_zip_paths
|
||
end
|
||
|
||
def zip_bid(bid)
|
||
# Todo: User Access Controll
|
||
|
||
homeattaches = bid.homeworks
|
||
#记录所有作业是不是有附件,有一个附件就改为true
|
||
#has_file = false
|
||
# 得到每一个人所有文件打包的zip文件
|
||
# 并将每一个人的zip打包为一个并返回路径
|
||
user_zip_paths = homeattaches.map do |homeattach|
|
||
if homeattach.attachments.count > 0
|
||
zip_homework_by_user homeattach
|
||
#has_file = true unless has_file
|
||
end
|
||
end
|
||
zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER
|
||
end
|
||
|
||
def zip_homework_by_user(homeattach)
|
||
homeworks_attach_path = []
|
||
# 需要将所有homework.attachments遍历加入zip
|
||
# 并且返回zip路径
|
||
user_attaches_paths = homeattach.attachments.each do |attach|
|
||
homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1)
|
||
end
|
||
zipping("#{homeattach.user.name.to_s}_#{Time.now.to_i}.zip", homeworks_attach_path, OUTPUT_FOLDER, true)
|
||
end
|
||
|
||
|
||
def zipping(zip_name_refer, files_paths, output_path, is_attachment=false)
|
||
# 输入待打包的文件列表,已经打包文件定位到ouput_path
|
||
ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE')
|
||
input_filename = files_paths
|
||
|
||
rename_zipfile = zip_name_refer ||= "archive_#{Time.now.to_i}.zip"
|
||
zipfile_name = "#{output_path}/#{rename_zipfile}"
|
||
|
||
Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name))
|
||
|
||
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
||
input_filename.each do |filename|
|
||
rename_file = Time.now.to_i.to_s+ ic.iconv( (File.basename(filename)) ).to_s
|
||
rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment
|
||
|
||
zipfile.add(rename_file, filename)
|
||
end
|
||
zipfile.get_output_stream('ReadMe') do |os|
|
||
os.write 'Homeworks'
|
||
end
|
||
end
|
||
zipfile_name
|
||
rescue Errno => e
|
||
logger.error "[zipdown#zipping] ===> #{e}"
|
||
@error = e
|
||
end
|
||
def detect_content_type(name)
|
||
content_type = Redmine::MimeType.of(name)
|
||
content_type.to_s
|
||
end
|
||
|
||
def filename_to_real(name)
|
||
attach = Attachment.find_by_disk_filename(name)
|
||
attach.filename
|
||
end
|
||
end
|