diff --git a/Gemfile b/Gemfile index 58373cb06..70281fedf 100644 --- a/Gemfile +++ b/Gemfile @@ -58,8 +58,6 @@ group :test do #end end - # gem 'rspec-rails' , '2.13.1' - # gem 'guard-rspec','2.5.0' # Gems used only for assets and not required # in production environments by default. group :assets do diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 23b080d94..d458b73e4 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -108,7 +108,7 @@ class AttachmentsController < ApplicationController end rescue => e - redirect_to "http://" + (Setting.host_name.to_s) +"/file_not_found.html" + redirect_to "http: //" + (Setting.host_name.to_s) +"/file_not_found.html" end #更新资源文件类型 diff --git a/app/controllers/zipdown_controller.rb b/app/controllers/zipdown_controller.rb index d775767cc..9880a6382 100644 --- a/app/controllers/zipdown_controller.rb +++ b/app/controllers/zipdown_controller.rb @@ -1,140 +1,208 @@ -# 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" -# -# -# 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' -# end -# else -# logger.error "[ZipDown#assort] ===> #{params[:obj_class]} unKown !!" -# end -# send_file zipfile, :filename => bid.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 -# unless homework.attachments.empty? -# zipfile = zip_homework_by_user homework -# send_file zipfile, :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) + -# "_" + homework.name + ".zip", :type => detect_content_type(zipfile) 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 = [] -# bid.homeworks.each do |homeattach| -# unless homeattach.attachments.empty? -# bid_homework_path << zip_homework_by_user(homeattach) -# end -# end -# zipping "#{Time.now.to_i}_#{bid.name}.zip", bid_homework_path, OUTPUT_FOLDER -# end -# -# def zip_homework_by_user(homeattach) -# homeworks_attach_path = [] -# not_exist_file = [] -# # 需要将所有homework.attachments遍历加入zip -# # 并且返回zip路径 -# homeattach.attachments.each do |attach| -# if File.exist?(attach.diskfile) -# homeworks_attach_path << attach.diskfile -# else -# not_exist_file << attach.filename -# end -# end -# 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) -# end -# -# -# def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) -# # 输入待打包的文件列表,已经打包文件定位到ouput_path -# ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') -# input_filename = files_paths -# -# 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::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| -# input_filename.each do |filename| -# flag = true -# index = 1 -# rename_file = ic.iconv( (File.basename(filename)) ).to_s -# rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment -# -# 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 -# end -# 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 -# 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 \ No newline at end of file +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" + + #统一下载功能 + 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 + + 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 + } + 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 + send_file zipfile, :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) + + "_" + homework.name + ".zip", :type => detect_content_type(zipfile) 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 = [] + bid.homeworks.each do |homeattach| + unless homeattach.attachments.empty? + bid_homework_path << zip_homework_by_user(homeattach) + end + end + + 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) + } + + end + + def zip_homework_by_user(homeattach) + homeworks_attach_path = [] + not_exist_file = [] + # 需要将所有homework.attachments遍历加入zip + # 并且返回zip路径 + homeattach.attachments.each do |attach| + if File.exist?(attach.diskfile) + homeworks_attach_path << attach.diskfile + else + not_exist_file << attach.filename + end + end + 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) + end + + + def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) + # 输入待打包的文件列表,已经打包文件定位到ouput_path + ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') + + 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)) + + unless is_attachment + #都是zip合并,没必要再费力压缩了 + Zip.default_compression = Zlib::NO_COMPRESSION + else + Zip.default_compression = Zlib::DEFAULT_COMPRESSION + end + + Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| + files_paths.each do |filename| + flag = true + index = 1 + rename_file = ic.iconv( (File.basename(filename)) ).to_s + rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment + + 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 + end + 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 + end + zipfile_name + #rescue Errno => e + # logger.error "[zipdown#zipping] ===> #{e}" + # @error = e + end + + # 合理分配文件打包 + # 如果小于 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| + 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} + last_files.clear + else + ret_files << {files:last_files, count: last_files.count, index: ret_files.count+1} + 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? + 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 \ No newline at end of file diff --git a/app/views/bids/_homework_list.html.erb b/app/views/bids/_homework_list.html.erb index 86a58e494..a59997a62 100644 --- a/app/views/bids/_homework_list.html.erb +++ b/app/views/bids/_homework_list.html.erb @@ -23,7 +23,7 @@ (<%= @jours_count %>)