| 
							
								 | 
							
							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("#{homeattach.user.name.to_s}_#{Time.now.to_i}.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
 |