aboutsummaryrefslogtreecommitdiffstats
path: root/app/controllers/pdfresources_controller.rb
blob: a7df8d8cc6107d4d591ee3b8830df96246048c6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
class PdfresourcesController < ApplicationController
  before_action :set_pdfresource, only: %i[ show edit update destroy ]
  before_action :require_admin, only: %i[ new create update destroy ]

  # GET /pdfresources or /pdfresources.json
  def index
    @pdfresources = Pdfresource.all
  end

  # GET /pdfresources/1 or /pdfresources/1.json
  def show
  end

  # GET /pdfresources/new
  def new
    @pdfresource = Pdfresource.new
  end

  # GET /pdfresources/1/edit
  def edit
  end

  # POST /pdfresources or /pdfresources.json
  def create
    @pdfresource = Pdfresource.new(pdfresource_params)

    respond_to do |format|
      if @pdfresource.save
        process_pdfs(@pdfresource.pdfs)
        format.html { redirect_to @pdfresource, notice: "Resource was successfully created." }
        format.json { render :show, status: :created, location: @pdfresource }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @pdfresource.errors, status: :unprocessable_entity }
      end
    end
  end

  def process_pdfs(pdfs)
    pdfs.each do |pdf|
      pdf_path = ActiveStorage::Blob.service.send(:path_for, pdf.key)
      convert_pdf_to_images(pdf_path, @pdfresource)
    end
  end

  def convert_pdf_to_images(pdf_path, resource)
    page_count_output = MiniMagick::Tool::Identify.new do |identify|
      identify.format '%n'
      identify << pdf_path
    end

    page_count = page_count_output.size

    page_count.times do |index|
      image_path = "page-#{index + 1}.jpg"
      reduced_image_path = "reduced-page-#{index + 1}.jpg"
      MiniMagick::Tool::Magick.new do |magick|
        magick << "#{pdf_path}[#{index}]" # Process each PDF page individually
        magick << image_path
      end

      image_reduced = MiniMagick::Tool::Magick.new do |magick|
        magick << image_path
        magick << "-quality"
        magick << "40"
        magick.strip
        magick << "-resize"
        magick << "50%"
        magick << reduced_image_path
      end

      if File.exist?(reduced_image_path)
        image_blob = ActiveStorage::Blob.create_and_upload!(
          io: File.open(reduced_image_path),
          filename: "page-#{index + 1}.jpg",
          content_type: 'image/jpg'
        )
        resource.pdf_snapshots.attach(image_blob)

        File.delete(image_path) if File.exist?(image_path)
        File.delete(reduced_image_path) if File.exist?(reduced_image_path)
      else
        raise "Reduced image file wasn't created successfully: #{image_reduced}"
      end
    end
  end

  # PATCH/PUT /pdfresources/1 or /pdfresources/1.json
  def update
    respond_to do |format|
      if @pdfresource.update(pdfresource_params)
        format.html { redirect_to @pdfresource, notice: "Pdfresource was successfully updated." }
        format.json { render :show, status: :ok, location: @pdfresource }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @pdfresource.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /pdfresources/1 or /pdfresources/1.json
  def destroy
    @pdfresource.destroy!

    respond_to do |format|
      format.html { redirect_to pdfresources_path, status: :see_other, notice: "Pdfresource was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_pdfresource
    @pdfresource = Pdfresource.find(params.expect(:id))
  end

  # Only allow a list of trusted parameters through.
  def pdfresource_params
    params.expect(pdfresource: [:name, :stripe_product_id, :price, :age_range, :curriculum, :feature_slot, :description, :card_description, pdfs: [], thumbnails: []])
  end

  # must be admin!
  def require_admin
    unless Current.session.user&.is_admin
      redirect_to root_path, notice: "You must be an admin to perform this action."
    end
  end
end