|  |  | 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 |