Skip to content

Commit

Permalink
🎁 Add action to re-split PDF
Browse files Browse the repository at this point in the history
For applications that have already installed IiifPrint, you'll need to
manually add the following to your `config/routes.rb` file:

```ruby
mount IiifPrint::Engine, at: '/'
```

Related to:

- #292
- #294

Co-authored-by: LaRita Robinson <[email protected]>
  • Loading branch information
jeremyf and laritakr committed Nov 27, 2023
1 parent 9ea15c8 commit ff7f91e
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 34 deletions.
38 changes: 38 additions & 0 deletions app/controllers/iiif_print/split_pdfs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module IiifPrint
# Responsible for coordinating the request to resplit a PDF.
class SplitPdfsController < ApplicationController
before_action :authenticate_user!

def create
@file_set = FileSet.where(id: params[:file_set_id]).first
authorize_create_split_request!(@file_set)
IiifPrint::Jobs::RequestSplitPdfJob.perform_later(file_set: @file_set, user: current_user)
respond_to do |wants|
wants.html { redirect_to polymorphic_path([main_app, @file_set]), flash: t("iiif_print.file_set.split_submitted", id: @file_set.id) }
wants.json { render json: { id: @file_set.id, to_param: @file_set.to_param }, status: :ok }
end
end

private

##
# @param file_set [FileSet]
def authorize_create_split_request!(file_set)
# NOTE: Duplicates logic of Hyrax: https://github.com/samvera/hyrax/blob/b334e186e77691d7da8ed59ff27f091be1c2a700/app/controllers/hyrax/file_sets_controller.rb#L234-L241
#
# Namely if we don't have a file_set we need not proceed.
raise CanCan::AccessDenied unless file_set

##
# Rely on CanCan's authorize! method. We could add the :split_pdf action to the ability
# class. But we're pigging backing on the idea that you can do this if you can edit the work.
authorize!(:edit, file_set)
raise "Expected #{file_set.class} ID=#{file_set.id} #to_param=#{file_set.to_param} to be a PDF. Instead found mime_type of #{file_set.mime_type}." unless file_set.pdf?

work = IiifPrint.parent_for(file_set)
raise WorkNotConfiguredToSplitFileSetError.new(file_set: file_set, work: work) unless work&.iiif_print_config&.pdf_splitter_job&.presence

true
end
end
end
23 changes: 23 additions & 0 deletions app/views/hyrax/file_sets/_show_actions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="form-actions">
<% if Hyrax.config.analytics? %>
<% # turbolinks needs to be turned off or the page will use the cache and the %>
<% # analytics graph will not show unless the page is refreshed. %>
<%= link_to t('.analytics'), @presenter.stats_path, id: 'stats', class: 'btn btn-default', data: { turbolinks: false } %>
<% end %>
<% if @presenter.editor? && !workflow_restriction?(@presenter) %>
<%= link_to t(".edit_this", type: @presenter.human_readable_type), edit_polymorphic_path([main_app, @presenter]),
class: 'btn btn-default' %>
<%= link_to t(".delete_this", type: @presenter.human_readable_type), [main_app, @presenter],
class: 'btn btn-danger', data: { confirm: t(".confirm_delete_this", type: @presenter.human_readable_type) },
method: :delete %>
<% end %>

<% if @presenter.editor? && @presenter.pdf? %>
<%= link_to t("iiif_print.file_set.split_this"), split_pdf_path(@presenter),
class: 'btn btn-default', data: { confirm: t("iiif_print.file_set.confirm_split_this") },
method: :post %>
<% end %>

<%= render 'social_media' %>
</div>
4 changes: 4 additions & 0 deletions config/locales/iiif_print.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ en:
label: 'Place of publication'
publication_title:
label: 'Publication'
file_set:
split_this: 'Split PDF into multiple images.'
confirm_split_this: 'Split PDF into multiple images.'
split_submitted: 'Submitted PDF splitting job for FileSet ID=%{id}.'
newspapers_search:
title: 'Search Newspapers'
text: 'Use this form to search for full-text newspaper content.'
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
IiifPrint::Engine.routes.draw do
post "split_pdfs/:file_set_id" => "split_pdfs#create", as: :split_pdf
end
8 changes: 8 additions & 0 deletions lib/generators/iiif_print/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ def catalog_controller_configuration
generate 'iiif_print:catalog_controller'
end

def install_routes
return if IO.read('config/routes.rb').include?('mount IiifPrint::Engine')

inject_into_file 'config/routes.rb', after: /mount Hyrax::Engine\s*\n/ do
" mount IiifPrint::Engine, at: '/'\n"\
end
end

def inject_configuration
copy_file 'config/initializers/iiif_print.rb'
end
Expand Down
9 changes: 9 additions & 0 deletions lib/iiif_print/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,13 @@ class DataError < IiifPrintError

class MissingFileError < IiifPrintError
end

class WorkNotConfiguredToSplitFileSetError < IiifPrintError
def initialize(file_set:, work:)
message = "Expected that we would be splitting #{file_set.class} ID=#{file_set&.id} #to_param=#{file_set&.to_param} " \
"for work #{work.class} ID=#{work&.id} #to_param=#{work&.to_param}. " \
"However it was not configured for PDF splitting."
super(message)
end
end
end
38 changes: 38 additions & 0 deletions lib/iiif_print/jobs/request_split_pdf_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module IiifPrint
module Jobs
##
# Encapsulates logic for cleanup when the PDF is destroyed after pdf splitting into child works
class RequestSplitPdfJob < IiifPrint::Jobs::ApplicationJob
##
# @param file_set [FileSet]
# @param user [User]
# rubocop:disable Metrics/MethodLength
def perform(file_set:, user:)
return true if file_set.pdf?

work = IiifPrint.parent_for(file_set)

# Woe is ye who changes the configuration of the model, thus removing the splitting.
raise WorkNotConfiguredToSplitFileSetError.new(work: work, file_set: file_set) unless work&.iiif_print_config&.pdf_splitter_job&.presence

# clean up any existing spawned child works of this file_set
IiifPrint::SplitPdfs::DestroyPdfChildWorksService.conditionally_destroy_spawned_children_of(
file_set: file_set,
work: work
)

location = Hyrax::WorkingDirectory.find_or_retrieve(file_set.files.first.id, file_set.id)

# submit a job to split pdf into child works
work.iiif_print_config.pdf_splitter_job.perform_later(
file_set,
[location],
user,
work.admin_set_id,
0 # A no longer used parameter; but we need to preserve the method signature (for now)
)
end
# rubocop:enable Metrics/MethodLength
end
end
end
34 changes: 0 additions & 34 deletions lib/iiif_print/split_pdfs/pdf_child_works_service.rb

This file was deleted.

0 comments on commit ff7f91e

Please sign in to comment.