socialforge/app/controllers/zipdown_controller.rb

242 lines
7.8 KiB
Ruby
Raw Normal View History

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
def assort
if params[:obj_class] == "Bid"
bid = Bid.find params[:obj_id]
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'
return
end
else
logger.error "[ZipDown#assort] ===> #{params[:obj_class]} unKown !!"
end
# if zipfile
# if zipfile.length > 1
# @mut_down_files = zipfile #zipfile.each{|x| File.basename(x)}
# else
# send_file zipfile.first[:real_file], :filename => bid.name + ".zip", :type => detect_content_type(zipfile.first[:real_file])
# return
# end
# end
respond_to do |format|
format.json {
render json: zipfile.to_json
}
2015-03-10 09:31:30 +08:00
end
#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
unless homework.attachments.empty?
zipfile = zip_homework_by_user homework
2015-04-02 17:20:52 +08:00
send_file zipfile.file_path, :filename => ((homework.user.user_extensions.nil? || homework.user.user_extensions.student_id.nil?) ? "" : homework.user.user_extensions.student_id) +
"_" + (homework.user.lastname.nil? ? "" : homework.user.lastname) + (homework.user.firstname.nil? ? "" : homework.user.firstname) +
2015-04-02 17:20:52 +08:00
"_" + homework.name + ".zip", :type => detect_content_type(zipfile.file_path) if(zipfile)
else
render file: 'public/no_file_found.html'
end
else
render file: 'public/file_not_found.html'
end
else
render_403
end
#rescue => e
# render file: 'public/file_not_found.html'
end
private
#通过作业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 zip_bid(bid)
# Todo: User Access Controll
bid_homework_path = []
2015-04-02 17:20:52 +08:00
digests = []
bid.homeworks.each do |homeattach|
unless homeattach.attachments.empty?
2015-04-02 17:20:52 +08:00
out_file = zip_homework_by_user(homeattach)
bid_homework_path << out_file.file_path
digests << out_file.file_digest
end
end
2015-03-10 09:31:30 +08:00
2015-04-02 17:20:52 +08:00
homework_id = bid.id
user_id = bid.author_id
2015-03-10 09:31:30 +08:00
2015-04-02 17:20:52 +08:00
out_file = find_or_pack(homework_id, user_id, digests.sort){
zipping("#{Time.now.to_i}_#{bid.name}.zip",
bid_homework_path, OUTPUT_FOLDER)
2015-03-10 09:31:30 +08:00
}
2015-04-02 17:20:52 +08:00
# zips = split_pack_files(bid_homework_path, Setting.pack_attachment_max_size.to_i*1024)
# x = 0
#
#
# zips.each { |o|
# x += 1
# file = zipping "#{Time.now.to_i}_#{bid.name}_#{x}.zip", o[:files], OUTPUT_FOLDER
# o[:real_file] = file
# o[:file] = File.basename(file)
# o[:size] = (File.size(file) / 1024.0 / 1024.0).round(2)
# }
[{files:[out_file.file_path], count: 1, index: 1,
real_file: out_file.file_path, file: File.basename(out_file.file_path),
size:(out_file.pack_size / 1024.0 / 1024.0).round(2)
}]
end
2015-04-02 17:20:52 +08:00
def zip_homework_by_user(homework_attach)
2014-10-30 09:33:30 +08:00
homeworks_attach_path = []
not_exist_file = []
2014-10-30 09:33:30 +08:00
# 需要将所有homework.attachments遍历加入zip
2015-04-02 17:20:52 +08:00
digests = []
homework_attach.attachments.each do |attach|
if File.exist?(attach.diskfile)
homeworks_attach_path << attach.diskfile
2015-04-02 17:20:52 +08:00
digests << attach.digest
else
not_exist_file << attach.filename
2015-04-02 17:20:52 +08:00
digests << 'not_exist_file'
end
2014-10-30 09:33:30 +08:00
end
2015-04-02 17:20:52 +08:00
out_file = find_or_pack(homework_attach.bid_id, homework_attach.user_id, digests.sort){
zipping("#{homework_attach.user.lastname}#{homework_attach.user.firstname}_#{((homework_attach.user.user_extensions.nil? || homework_attach.user.user_extensions.student_id.nil?) ? "" : homework_attach.user.user_extensions.student_id)}_#{Time.now.to_i.to_s}.zip",
homeworks_attach_path, OUTPUT_FOLDER, true, not_exist_file)
}
end
2015-04-02 17:20:52 +08:00
def find_or_pack(homework_id, user_id, digests)
raise "please given a pack block" unless block_given?
2015-04-02 17:20:52 +08:00
out_file = ZipPack.packed?(homework_id, user_id, digests.sort)
2015-04-02 17:20:52 +08:00
unless out_file && out_file.file_valid?
file = yield
2015-04-02 17:20:52 +08:00
ZipPack.where(homework_id: homework_id,
user_id: user_id).delete_all
out_file = ZipPack.create(homework_id: homework_id,
user_id: user_id,
file_digest: Trustie::Utils.digest(file),
file_path: file,
pack_size: File.size(file),
file_digests: digests.join(',')
)
2015-03-10 09:31:30 +08:00
else
2015-04-02 17:20:52 +08:00
out_file.pack_times = out_file.pack_times + 1
out_file.save
2015-03-10 09:31:30 +08:00
end
2015-04-02 17:20:52 +08:00
out_file
end
def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[])
rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip"
zipfile_name = "#{output_path}/#{rename_zipfile}"
Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name))
Zip::Archive.open(zipfile_name, Zip::CREATE) do |zipfile|
2015-03-10 09:31:30 +08:00
files_paths.each do |filename|
flag = true
index = 1
2015-04-02 17:20:52 +08:00
rename_file = File.basename(filename)
rename_file = filename_to_real( File.basename(filename)) if is_attachment
begin
2015-04-02 17:20:52 +08:00
zipfile.add_file(rename_file, filename)
flag = false
rescue Exception => e
2015-04-02 17:20:52 +08:00
zipfile.add_buffer('FILE_NOTICE.txt', l(:label_file_exist))
next
end
2014-10-30 09:33:30 +08:00
end
unless not_exist_file.empty?
2015-04-02 17:20:52 +08:00
zipfile.add_buffer('FILE_LOST.txt', l(:label_file_lost) + not_exist_file.join(',').to_s)
end
end
zipfile_name
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_with_index do |f,i|
2015-03-10 09:31:30 +08:00
if (max_size += File.size(f)) > pack_attachment_max_size
max_size = 0
if last_files.empty? #如果单个文件超过大小,也将此文件作为一组
ret_files << {files: [f], count: 1, index: ret_files.count+1}
2015-03-10 09:31:30 +08:00
last_files.clear
else
ret_files << {files:last_files, count: last_files.count, index: ret_files.count+1}
2015-03-10 09:31:30 +08:00
last_files.clear
redo
end
else
last_files << f
end
end
ret_files << {files:last_files, count: last_files.count, index: ret_files.count+1} unless last_files.empty?
2015-03-10 09:31:30 +08:00
ret_files
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