Skip to content

Commit

Permalink
Basic file status
Browse files Browse the repository at this point in the history
This adds a PreIngestWork controller that allows
you to get the thumbnail URLs for a work based on
the deduplication_key.

This is used by some JS that checks the thumbnail URLs
by only requesting headers from the URL. If the work's
files have been characterized the requests will return
200. That's used to change change the icon from a question
mark to a green check in the 'Works and Files' page.

This kind of status checking can't be used for individual files
right now because there isn't any unique information being
saved on the `FileSet` that would be present when the `PreIngestFile`
is created.

Connected to https://github.com/curationexperts/in-house/issues/423
  • Loading branch information
little9 authored and bess committed Nov 13, 2019
1 parent 3f3150e commit 472df2b
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 28 deletions.
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ RSpec/DescribeClass:

RSpec/ExampleLength:
Exclude:
- 'spec/controllers/pre_ingest_works_controller_spec.rb'
- 'spec/zizia/hyrax/hyrax_basic_metadata_mapper_spec.rb'
- 'spec/integration/import_hyrax_csv.rb'
- 'spec/integration/csv_import_detail_spec.rb'
Expand Down
44 changes: 43 additions & 1 deletion app/assets/javascripts/zizia/zizia.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
var Zizia = {
displayUploadedFile: function() {
displayUploadedFile: function () {
var DisplayUploadedFile = require('zizia/DisplayUploadedFile')
new DisplayUploadedFile().display()
},
checkStatuses: function (options) {
var results = []
// Go through the list of thumbnails for the work based
// on the deduplicationKey
options.thumbnails.forEach(function (thumbnail) {
$.ajax({
type: 'HEAD',
url: thumbnail,
complete: function (xhr) {
// Request only the headers from the thumbnail url
// push the statuses into an array
results.push(xhr.getResponseHeader('status'))
// See how many urls are not returning 200
var missingThumbnailCount = results.filter(
function (status) {
if (status !== '200 OK') { return true }
}).length
// If there are any not returning 200, the work is still being processed
if (missingThumbnailCount > 0) {

} else {
Zizia.addSuccessClasses(options)
}
}
})
})
},
displayWorkStatus: function () {
$('[id^=work-status]').each(function () {
var deduplicationKey = $(this)[0].id.split('work-status-')[1]
$.get('/pre_ingest_works/thumbnails/' + deduplicationKey, function (data) {
data.deduplicationKey = deduplicationKey
Zizia.checkStatuses(data)
})
})
},
addSuccessClasses: function (options) {
$('#work-status-' + options.deduplicationKey + ' > span').removeClass('status-unknown')
$('#work-status-' + options.deduplicationKey + ' > span').removeClass('glyphicon-question-sign')
$('#work-status-' + options.deduplicationKey + ' > span').addClass('text-success')
$('#work-status-' + options.deduplicationKey + ' > span').addClass('glyphicon-ok-sign')
}
}
32 changes: 32 additions & 0 deletions app/controllers/zizia/pre_ingest_works_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module Zizia
class PreIngestWorksController < ::ApplicationController
before_action :merge_abilities
load_and_authorize_resource

def thumbnails
pre_ingest_work = Zizia::PreIngestWork.where(deduplication_key: pre_ingest_works_params[:deduplication_key]).first

@thumbnails = if pre_ingest_work
pre_ingest_work.thumbnails
else
[]
end

respond_to do |format|
format.json { render json: { thumbnails: @thumbnails } }
end
end

private

def pre_ingest_works_params
params.permit(:deduplication_key, :format)
end

def merge_abilities
current_ability.merge(Zizia::Ability.new(current_user))
end
end
end
15 changes: 15 additions & 0 deletions app/models/zizia/ability.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true
module Zizia
class Ability
include Hydra::Ability
include Hyrax::Ability
self.ability_logic += [:everyone_can_create_curation_concerns]

# Define any customized permissions here.
def custom_permissions
can :manage, Zizia::CsvImport if current_user.admin?
can :manage, Zizia::CsvImportDetail if current_user.admin?
can :manage, Zizia::PreIngestWork if current_user.admin?
end
end
end
4 changes: 0 additions & 4 deletions app/models/zizia/csv_import_detail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ class CsvImportDetail < ::ApplicationRecord
has_many :pre_ingest_works
has_many :pre_ingest_files, through: :pre_ingest_works

def status
'undetermined'
end

def total_size
return 0 if pre_ingest_files.empty?
pre_ingest_files.map(&:size).sum
Expand Down
15 changes: 15 additions & 0 deletions app/models/zizia/pre_ingest_work.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,20 @@ def title
return solr_title unless solr_title.nil?
'This work\'s metadata has not been indexed yet.'
end

# Returns thumbnail urls based on the work's deduplication_key
# @return [Array<String>] the work's thumbnail urls
def thumbnails
thumbnail_urls = []
return thumbnail_urls if deduplication_key.nil?
file_sets = ActiveFedora::SolrService.get("deduplication_key_tesim:#{deduplication_key}")
.dig('response', 'docs', 0, 'file_set_ids_ssim')
return thumbnail_urls unless file_sets
file_sets.each do |file_set_id|
thumbnail_urls.push(ActiveFedora::SolrService.get("id:#{file_set_id}")
.dig('response', 'docs', 0, 'thumbnail_path_ss'))
end
thumbnail_urls
end
end
end
4 changes: 0 additions & 4 deletions app/views/zizia/csv_import_details/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<th>Number of Works</th>
<th>Number of Files</th>
<th>Total Size</th>
<th>Status</th>
<th>Overwrite Behavior Type</th>
</tr>
<% @csv_import_details.each do |csv_import_detail| %>
Expand All @@ -35,9 +34,6 @@
<td>
<%= number_to_human_size(csv_import_detail.total_size) %>
</td>
<td>
<%= csv_import_detail.status %>
</td>
<td>
<%= human_update_actor_stack(csv_import_detail.update_actor_stack) %>
</td>
Expand Down
9 changes: 9 additions & 0 deletions app/views/zizia/csv_import_details/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<th>Title</th>
<th>Files</th>
<th>Date</th>
<th>Status</th>
</tr>
<% @pre_ingest_works.each do |pre_ingest_work| %>
<tr>
Expand All @@ -30,8 +31,16 @@
<td>
<%= pre_ingest_work.created_at.strftime("%B %-d, %Y %H:%M") %>
</td>
<td id="<%= "work-status-#{pre_ingest_work.deduplication_key}" %>">
<span class="glyphicon glyphicon-question-sign status-unknown"></span>
</td>
</tr>
<% end %>
</table>
<%= paginate @pre_ingest_works %>
</div>
<script>
$(document).on('turbolinks:load', function() {
Zizia.displayWorkStatus()
})
</script>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@

get 'csv_import_details/index'
get 'csv_import_details/show/:id', to: 'csv_import_details#show', as: 'csv_import_detail'
get 'pre_ingest_works/thumbnails/:deduplication_key', to: 'pre_ingest_works#thumbnails'
end
56 changes: 56 additions & 0 deletions spec/controllers/pre_ingest_works_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Zizia::PreIngestWorksController, :clean, type: :controller do
routes { Zizia::Engine.routes }
let(:admin_user) { FactoryBot.create(:admin) }
let(:pre_ingest_work) { FactoryBot.create(:pre_ingest_work) }
let(:pre_ingest_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id) }
let(:pre_ingest_file_without_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id, filename: File.open([Zizia::Engine.root, '/', 'spec/fixtures/dog.jpg'].join)) }
let(:work) { Work.new(title: ['a title'], deduplication_key: pre_ingest_work.deduplication_key) }
let(:file_set) do
FactoryBot.create(:file_set,
title: ['zizia.png'],
content: File.open([Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join))
end
let(:basename) { 'zizia.png' }
before do
work.ordered_members << file_set
work.save
end

describe 'GET thumbnails' do
context 'as a logged in user' do
it 'returns 200' do
allow(controller).to receive(:current_user).and_return(admin_user)
get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json }
expect(response.status).to eq(200)
end

it 'returns an array of thumbail paths' do
file_set.save
allow(controller).to receive(:current_user).and_return(admin_user)
get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json }
parsed_json = JSON.parse(response.body)
expect(parsed_json['thumbnails']).to be_an(Array)
expect(parsed_json['thumbnails'].empty?).to eq(false)
end

it 'returns an empty array if there aren\'t any thumbnails' do
allow(controller).to receive(:current_user).and_return(admin_user)
get :thumbnails, params: { deduplication_key: 'abc/1234', format: :json }
parsed_json = JSON.parse(response.body)
expect(parsed_json['thumbnails']).to be_an(Array)
expect(parsed_json['thumbnails'].empty?).to eq(true)
end
end

context 'as someone not logged in' do
it 'returns 401' do
get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json }
expect(response.status).to eq(401)
end
end
end
end
40 changes: 24 additions & 16 deletions spec/dummy/spec/system/csv_import_details_page_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'rails_helper'
include Warden::Test::Helpers

RSpec.describe 'viewing the csv import detail page', js: true do
RSpec.describe 'viewing the csv import detail page', :clean, js: true do
let(:user) { FactoryBot.create(:admin, email: '[email protected]')}
let(:second_user) { FactoryBot.create(:user, email: '[email protected]') }
let(:csv_import) { FactoryBot.create(:csv_import) }
Expand All @@ -11,6 +11,14 @@
let(:csv_import_detail_third) { FactoryBot.create(:csv_import_detail, created_at: Time.parse('Wed, 30 Oct 2019 14:20:02 UTC +00:00').utc, depositor_id: second_user.id, csv_import_id: 2) }
let(:csv_pre_ingest_works) { FactoryBot.create_list(:pre_ingest_work, 12, csv_import_detail_id: 4) }
let(:csv_pre_ingest_work_second) { FactoryBot.create(:pre_ingest_work, csv_import_detail_id: 5, created_at: Time.parse('Thur, 31 Oct 2019 14:20:02 UTC +00:00').utc) }
let(:pre_ingest_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: csv_pre_ingest_work_second.id) }
let(:file_set) do
FactoryBot.create(:file_set,
title: ['zizia.png'],
content: File.open([Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join))
end
let(:work) { Work.new(title: ['a title'], deduplication_key: csv_pre_ingest_work_second.deduplication_key) }


before do
user.save
Expand All @@ -27,14 +35,16 @@
csv_import_detail_third.save
csv_pre_ingest_works.each(&:save)
csv_pre_ingest_work_second.save
pre_ingest_file.save

work.ordered_members << file_set
work.save
login_as user
end

it 'displays the metadata when you visit the page' do
visit ('/csv_import_details/index')
expect(page).to have_content('ID')
expect(page).to have_content('Status')
expect(page).to have_content('undetermined')
click_on '1'
expect(page).to have_content('Total Size')
expect(page).to have_content('Deduplication Key')
Expand All @@ -55,12 +65,6 @@
expect(page).to have_link '13'
end

it 'has a sortable status' do
pending 'status is always undetermined currently'
visit('/csv_import_details/index?direction=asc&locale=en&sort=status')
expect(page).to have_content 'zippy'
end

it 'has a sortable date' do
visit('/csv_import_details/index?direction=desc&locale=en&sort=created_at')
expect(page).to have_content 'October 31'
Expand All @@ -79,12 +83,6 @@
expect(page).to have_content('October 29, 2019 14:20')
end

it 'displays undetermined for the status' do
visit ('/csv_import_details/index')
expect(page).to have_content('Status')
expect(page).to have_content('undetermined')
end

it 'displays the overwrite behavior type' do
visit ('/csv_import_details/index')
expect(page).to have_content('Overwrite Behavior Type')
Expand All @@ -100,7 +98,6 @@

visit('/csv_import_details/index')
expect(page).to have_content('Next')

end

it 'has pagination at 10' do
Expand Down Expand Up @@ -134,4 +131,15 @@
click_on 'View Files'
expect(page).to have_content 'Row Number'
end

it 'can show a status for a file' do
file_set
visit('/csv_import_details/index')
click_on '5'
expect(page).to have_content 'View Files'
expect(page).to have_content 'Status'
expect(page.html).to match(/glyphicon-question-sign/)
click_on 'View Files'
expect(page).to have_content('Filename')
end
end
36 changes: 36 additions & 0 deletions spec/factories/file_sets.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true
FactoryBot.define do
factory :file_set do
transient do
user { build(:user) }
title { nil }
content { nil }
end
after(:build) do |fs, evaluator|
fs.apply_depositor_metadata evaluator.user.user_key
fs.title = evaluator.title
end

after(:create) do |file, evaluator|
Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content
end

trait :public do
read_groups { ["public"] }
end

trait :registered do
read_groups { ["registered"] }
end

factory :file_with_work do
after(:build) do |file, _evaluator|
file.title = ['testfile']
end
after(:create) do |file, evaluator|
Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content
create(:work, user: evaluator.user).members << file
end
end
end
end
2 changes: 1 addition & 1 deletion spec/factories/pre_ingest_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
updated_at { Time.current }
row_number { 1 }
row { 'sample,row' }
filename { '/a/path/to/my.csv' }
filename { [Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join }
size { 100_203_424 }
end
end
Loading

0 comments on commit 472df2b

Please sign in to comment.