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' , :layout => 'course_base' #logger.error "[ZipDown] ===> #{e}" #@error = e 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 #zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER 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 #unless has_file # render file: 'public/no_file_fond.html' , :layout => 'course_base' #end zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER #@paths = homeworks_attach_path #zipfile = ziping homeworks_attach_path #send_file zipfile, :filename => bid.name, # :type => detect_content_type(zipfile) #rescue Errno::ENOENT => e # logger.error "[Errno::ENOENT] ===> #{e}" # @error = e end def zip_homework_by_user(homeattach) #if homeattach.attachments.count > 0 homeworks_attach_path = [] # 需要将所有homework.attachments遍历加入zip # 并且返回zip路径 user_attaches_paths = homeattach.attachments.each do |attach| #length = attach.storage_path.length homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) end zipping("#{homework.user.user_extensions.student_id}_#{homeattach.user.name.to_s}.zip", homeworks_attach_path, OUTPUT_FOLDER, true) #user_attaches_paths #end 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 ziping files_path # ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') # folder = SaveFolder # input_filename = files_path # zipfile_name = "#{OutputFolder}/archive_#{Time.now.to_i}.zip" # # 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| # zipfile.add(ic.iconv(filename_to_real(File.basename(filename))), folder + '/' + filename) # end # zipfile.get_output_stream("ReadMe") { |os| # os.write "Homeworks" # } # 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