unepwcmc/SAPI

View on GitHub
app/controllers/checklist/documents_controller.rb

Summary

Maintainability
A
3 hrs
Test Coverage
class Checklist::DocumentsController < ApplicationController

  def index
    return render :json => []  if params[:taxon_concepts_ids].nil?
    return render :json => []  unless params[:taxon_concepts_ids].kind_of?(Array)
    anc_ids = MaterialDocIdsRetriever.ancestors_ids(params[:taxon_concepts_ids].first)
    chi_ids = MTaxonConcept.descendants_ids(params[:taxon_concepts_ids].first).map(&:to_i)
    params[:taxon_concepts_ids] = anc_ids | chi_ids
    @search = DocumentSearch.new(
      params.merge(show_private: !access_denied?, per_page: 10_000), 'public'
    )

    render :json => @search.cached_results,
      each_serializer: Checklist::DocumentSerializer,
      meta: {
        total: @search.cached_total_cnt,
        page: @search.page,
        per_page: @search.per_page
      }
  end

  def show
    @document = Document.find(params[:id])
    path_to_file = @document.filename.path unless @document.is_link?
    if access_denied? && !@document.is_public
      render_403
    elsif @document.is_link?
      redirect_to @document.filename.model[:filename]
    elsif !File.exists?(path_to_file)
      render_404
    else
      response.headers['Content-Length'] = File.size(path_to_file).to_s
      send_file(
        path_to_file,
          :filename => File.basename(path_to_file),
          :type => @document.filename.content_type,
          :disposition => 'attachment',
          :url_based_filename => true
      )
    end
  end

  def check_doc_presence
    doc_ids = MaterialDocIdsRetriever.run(params.dup.permit!.to_h)

    render :json => doc_ids.present?
  end

  def volume_download

    t = full_volume_downloader

    volumes = params[:volume].sort.join(',')


    send_file t.path,
      :type => "application/zip",
      :filename => "Identifications-documents-volume-#{volumes}.zip"

    t.close
  end

  private

  def access_denied?
    !current_user || current_user.is_api_user_or_secretariat?
  end

  def render_404
    render file: "#{Rails.root}/public/404", layout: false, formats: [:html],
    status: 404
  end

  def render_403
    render file: "#{Rails.root}/public/403", layout: false, formats: [:html],
    status: 403
  end

  def full_volume_downloader
    t = Tempfile.new('tmp-zip-' + request.remote_ip)
    missing_files = []
    vol_path = [Rails.root, '/public/ID_manual_volumes/', params['locale'], '/'].join
    @pdf_file_paths = params['volume'].map { |vol| vol_path + "Volume#{vol}" + "_#{params['locale'].upcase}" + '.pdf' }
    Zip::OutputStream.open(t.path) do |zos|
      @pdf_file_paths.each do |doc_path|
        path_to_file = doc_path.rpartition('/').first
        filename = doc_path.rpartition('/').last
        unless File.exists?(doc_path)
          missing_files <<
            "{\n  path: #{path_to_file},\n  filename: #{filename}\n}"
        else
          zos.put_next_entry("Identification-materials-#{filename}")
          zos.print IO.read(doc_path)
        end
        if missing_files.present?
          if missing_files.length == @pdf_file_paths.count
            render_404 && return
          end
          zos.put_next_entry('missing_files.txt')
          zos.print missing_files.join("\n\n")
        end
      end
    end
    t
  end
end