2014-09-15 10:58:14 +08:00
|
|
|
|
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"
|
|
|
|
|
|
2015-03-10 09:31:30 +08:00
|
|
|
|
#统一下载功能
|
|
|
|
|
def download
|
|
|
|
|
begin
|
|
|
|
|
send_file "#{OUTPUT_FOLDER}/#{params[:file]}", :filename => params[:filename], :type => detect_content_type(params[:file])
|
|
|
|
|
rescue => e
|
|
|
|
|
render file: 'public/no_file_found.html'
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-01-31 11:14:55 +08:00
|
|
|
|
|
2014-09-15 10:58:14 +08:00
|
|
|
|
def assort
|
2014-11-11 11:16:37 +08:00
|
|
|
|
if params[:obj_class] == "Bid"
|
|
|
|
|
bid = Bid.find params[:obj_id]
|
2014-11-24 15:56:23 +08:00
|
|
|
|
file_count = 0
|
|
|
|
|
bid.homeworks.map { |homework| file_count += homework.attachments.count}
|
|
|
|
|
if file_count > 0
|
|
|
|
|
zipfile = zip_bid bid
|
|
|
|
|
else
|
|
|
|
|
render file: 'public/no_file_found.html'
|
|
|
|
|
end
|
2014-11-11 11:16:37 +08:00
|
|
|
|
else
|
|
|
|
|
logger.error "[ZipDown#assort] ===> #{params[:obj_class]} unKown !!"
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
|
2015-03-10 09:31:30 +08:00
|
|
|
|
if zipfile
|
|
|
|
|
if zipfile.length > 1
|
|
|
|
|
@mut_down_files = zipfile.map{|x| File.basename(x)}
|
|
|
|
|
else
|
|
|
|
|
send_file zipfile, :filename => bid.name + ".zip", :type => detect_content_type(zipfile)
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-01-10 10:55:37 +08:00
|
|
|
|
#rescue Exception => e
|
|
|
|
|
# render file: 'public/no_file_found.html'
|
2014-09-15 10:58:14 +08:00
|
|
|
|
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
|
2014-11-11 11:16:37 +08:00
|
|
|
|
unless homework.attachments.empty?
|
2014-09-15 10:58:14 +08:00
|
|
|
|
zipfile = zip_homework_by_user homework
|
2014-12-12 09:46:12 +08:00
|
|
|
|
send_file zipfile, :filename => ((homework.user.user_extensions.nil? || homework.user.user_extensions.student_id.nil?) ? "" : homework.user.user_extensions.student_id) +
|
2014-12-10 17:04:22 +08:00
|
|
|
|
"_" + (homework.user.lastname.nil? ? "" : homework.user.lastname) + (homework.user.firstname.nil? ? "" : homework.user.firstname) +
|
|
|
|
|
"_" + homework.name + ".zip", :type => detect_content_type(zipfile) if(zipfile)
|
2014-09-15 10:58:14 +08:00
|
|
|
|
else
|
2014-11-11 11:16:37 +08:00
|
|
|
|
render file: 'public/no_file_found.html'
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
else
|
2014-11-11 11:16:37 +08:00
|
|
|
|
render file: 'public/file_not_found.html'
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
else
|
2014-11-11 11:16:37 +08:00
|
|
|
|
render_403
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
2015-01-10 10:55:37 +08:00
|
|
|
|
#rescue => e
|
|
|
|
|
# render file: 'public/file_not_found.html'
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
2015-01-10 10:55:37 +08:00
|
|
|
|
#通过作业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
|
|
|
|
|
|
2014-09-15 10:58:14 +08:00
|
|
|
|
def zip_bid(bid)
|
|
|
|
|
# Todo: User Access Controll
|
2014-11-11 11:16:37 +08:00
|
|
|
|
bid_homework_path = []
|
|
|
|
|
bid.homeworks.each do |homeattach|
|
|
|
|
|
unless homeattach.attachments.empty?
|
|
|
|
|
bid_homework_path << zip_homework_by_user(homeattach)
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
2015-03-10 09:31:30 +08:00
|
|
|
|
|
|
|
|
|
zips = split_pack_files(bid_homework_path, Setting.pack_attachment_max_size.to_i)
|
|
|
|
|
x = 0
|
|
|
|
|
|
|
|
|
|
zips.map { |o|
|
|
|
|
|
x += 1
|
|
|
|
|
zipping "#{Time.now.to_i}_#{bid.name}_#{x}.zip", o, OUTPUT_FOLDER
|
|
|
|
|
}
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def zip_homework_by_user(homeattach)
|
2014-10-30 09:33:30 +08:00
|
|
|
|
homeworks_attach_path = []
|
2015-01-09 15:59:42 +08:00
|
|
|
|
not_exist_file = []
|
2014-10-30 09:33:30 +08:00
|
|
|
|
# 需要将所有homework.attachments遍历加入zip
|
|
|
|
|
# 并且返回zip路径
|
2014-11-11 11:16:37 +08:00
|
|
|
|
homeattach.attachments.each do |attach|
|
2015-01-09 15:59:42 +08:00
|
|
|
|
if File.exist?(attach.diskfile)
|
|
|
|
|
homeworks_attach_path << attach.diskfile
|
|
|
|
|
else
|
|
|
|
|
not_exist_file << attach.filename
|
|
|
|
|
end
|
2014-10-30 09:33:30 +08:00
|
|
|
|
end
|
2015-01-09 15:59:42 +08:00
|
|
|
|
zipping("#{homeattach.user.lastname}#{homeattach.user.firstname}_#{((homeattach.user.user_extensions.nil? || homeattach.user.user_extensions.student_id.nil?) ? "" : homeattach.user.user_extensions.student_id)}_#{Time.now.to_i.to_s}.zip", homeworks_attach_path, OUTPUT_FOLDER, true, not_exist_file)
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2015-01-09 15:59:42 +08:00
|
|
|
|
def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[])
|
2014-09-15 10:58:14 +08:00
|
|
|
|
# 输入待打包的文件列表,已经打包文件定位到ouput_path
|
|
|
|
|
ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE')
|
|
|
|
|
|
2014-11-11 14:41:07 +08:00
|
|
|
|
rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip"
|
2014-09-15 10:58:14 +08:00
|
|
|
|
zipfile_name = "#{output_path}/#{rename_zipfile}"
|
|
|
|
|
|
|
|
|
|
Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name))
|
|
|
|
|
|
2015-03-10 09:31:30 +08:00
|
|
|
|
unless is_attachment
|
|
|
|
|
#都是zip合并,没必要再费力压缩了
|
|
|
|
|
Zip.default_compression = Zlib::NO_COMPRESSION
|
|
|
|
|
else
|
|
|
|
|
Zip.default_compression = Zlib::DEFAULT_COMPRESSION
|
|
|
|
|
end
|
|
|
|
|
|
2014-09-15 10:58:14 +08:00
|
|
|
|
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
2015-03-10 09:31:30 +08:00
|
|
|
|
files_paths.each do |filename|
|
2015-01-10 17:41:50 +08:00
|
|
|
|
flag = true
|
|
|
|
|
index = 1
|
2014-11-11 11:39:57 +08:00
|
|
|
|
rename_file = ic.iconv( (File.basename(filename)) ).to_s
|
2014-10-30 09:33:30 +08:00
|
|
|
|
rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment
|
2014-09-15 10:58:14 +08:00
|
|
|
|
|
2015-01-10 17:41:50 +08:00
|
|
|
|
begin
|
|
|
|
|
zipfile.add(rename_file, filename)
|
|
|
|
|
flag = false
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
zipfile.get_output_stream('FILE_NOTICE.txt') do |os|
|
|
|
|
|
os.write l(:label_file_exist)
|
|
|
|
|
end
|
|
|
|
|
next
|
|
|
|
|
end
|
2014-10-30 09:33:30 +08:00
|
|
|
|
end
|
2015-01-09 15:59:42 +08:00
|
|
|
|
unless not_exist_file.empty?
|
|
|
|
|
zipfile.get_output_stream('FILE_LOST.txt') do |os|
|
|
|
|
|
os.write l(:label_file_lost) + not_exist_file.join(',').to_s
|
|
|
|
|
end
|
|
|
|
|
end
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
|
|
|
|
zipfile_name
|
2015-01-10 10:55:37 +08:00
|
|
|
|
#rescue Errno => e
|
|
|
|
|
# logger.error "[zipdown#zipping] ===> #{e}"
|
|
|
|
|
# @error = e
|
2014-09-15 10:58:14 +08:00
|
|
|
|
end
|
2015-03-10 09:31:30 +08:00
|
|
|
|
|
|
|
|
|
# 合理分配文件打包
|
|
|
|
|
# 如果小于 pack_attachment_max_size, 则返回单个文件
|
|
|
|
|
# 反之则切分为多个文件组返回
|
|
|
|
|
def split_pack_files(files, pack_attachment_max_size)
|
|
|
|
|
max_size = 0
|
|
|
|
|
last_files = []
|
|
|
|
|
ret_files = []
|
|
|
|
|
files.each do |f|
|
|
|
|
|
if (max_size += File.size(f)) > pack_attachment_max_size
|
|
|
|
|
max_size = 0
|
|
|
|
|
if last_files.empty? #如果单个文件超过大小,也将此文件作为一组
|
|
|
|
|
ret_files << [f]
|
|
|
|
|
last_files.clear
|
|
|
|
|
else
|
|
|
|
|
ret_files << last_files
|
|
|
|
|
last_files.clear
|
|
|
|
|
redo
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
last_files << f
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
ret_files << last_files unless last_files.empty?
|
|
|
|
|
ret_files
|
|
|
|
|
end
|
|
|
|
|
|
2014-09-15 10:58:14 +08:00
|
|
|
|
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
|
2015-01-09 15:59:42 +08:00
|
|
|
|
end
|