bulk_ops 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/assets/images/bulk_ops/github_logo.png +0 -0
- data/app/assets/javascripts/bulk_ops.js +14 -0
- data/app/assets/javascripts/bulk_ops/selections.js +24 -0
- data/app/assets/javascripts/selections.js +38 -0
- data/app/assets/javascripts/work_search.js +64 -0
- data/app/assets/stylesheets/bulk_ops.scss +99 -0
- data/app/controllers/bulk_ops/application_controller.rb +13 -0
- data/app/controllers/bulk_ops/github_authorization_controller.rb +33 -0
- data/app/controllers/bulk_ops/operations_controller.rb +481 -0
- data/app/jobs/bulk_ops/application_job.rb +4 -0
- data/app/mailers/bulk_ops/application_mailer.rb +6 -0
- data/app/models/bulk_ops/application_record.rb +5 -0
- data/app/views/bulk_ops/_bulk_ops_sidebar_widget.html.erb +15 -0
- data/app/views/bulk_ops/_github_auth_widget.html.erb +13 -0
- data/app/views/bulk_ops/operations/_bulk_ops_header.html.erb +4 -0
- data/app/views/bulk_ops/operations/_choose_fields.html.erb +22 -0
- data/app/views/bulk_ops/operations/_choose_notifications.html.erb +22 -0
- data/app/views/bulk_ops/operations/_git_message.html.erb +7 -0
- data/app/views/bulk_ops/operations/_ingest_options.html.erb +42 -0
- data/app/views/bulk_ops/operations/_operation_options.html.erb +38 -0
- data/app/views/bulk_ops/operations/_show_authorize.html.erb +13 -0
- data/app/views/bulk_ops/operations/_show_complete.html.erb +31 -0
- data/app/views/bulk_ops/operations/_show_draft.html.erb +20 -0
- data/app/views/bulk_ops/operations/_show_new.html.erb +2 -0
- data/app/views/bulk_ops/operations/_show_pending.html.erb +58 -0
- data/app/views/bulk_ops/operations/_show_running.html.erb +56 -0
- data/app/views/bulk_ops/operations/_show_verifying.html.erb +8 -0
- data/app/views/bulk_ops/operations/_show_waiting.html.erb +9 -0
- data/app/views/bulk_ops/operations/_update_draft_work_list.html.erb +45 -0
- data/app/views/bulk_ops/operations/_update_draft_work_search.html.erb +59 -0
- data/app/views/bulk_ops/operations/_update_options.html.erb +9 -0
- data/app/views/bulk_ops/operations/index.html.erb +51 -0
- data/app/views/bulk_ops/operations/new.html.erb +36 -0
- data/app/views/bulk_ops/operations/show.html.erb +7 -0
- data/config/routes.rb +25 -0
- data/db/migrate/20180926190757_create_github_credentials.rb +13 -0
- data/db/migrate/20181017180436_create_bulk_ops_tables.rb +40 -0
- data/lib/bulk_ops.rb +15 -0
- data/lib/bulk_ops/create_spreadsheet_job.rb +43 -0
- data/lib/bulk_ops/create_work_job.rb +14 -0
- data/lib/bulk_ops/delete_file_set_job.rb +15 -0
- data/lib/bulk_ops/engine.rb +6 -0
- data/lib/bulk_ops/error.rb +141 -0
- data/lib/bulk_ops/github_access.rb +284 -0
- data/lib/bulk_ops/github_credential.rb +3 -0
- data/lib/bulk_ops/operation.rb +358 -0
- data/lib/bulk_ops/relationship.rb +79 -0
- data/lib/bulk_ops/search_builder_behavior.rb +80 -0
- data/lib/bulk_ops/templates/configuration.yml +5 -0
- data/lib/bulk_ops/templates/readme.md +1 -0
- data/lib/bulk_ops/update_work_job.rb +14 -0
- data/lib/bulk_ops/verification.rb +210 -0
- data/lib/bulk_ops/verification_job.rb +23 -0
- data/lib/bulk_ops/version.rb +3 -0
- data/lib/bulk_ops/work_job.rb +104 -0
- data/lib/bulk_ops/work_proxy.rb +466 -0
- data/lib/generators/bulk_ops/install/install_generator.rb +27 -0
- data/lib/generators/bulk_ops/install/templates/config/github.yml.example +28 -0
- metadata +145 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
<div id="add-works" >
|
2
|
+
<h3>Find Works to add to update</h3>
|
3
|
+
|
4
|
+
<form id="ajax-work-search">
|
5
|
+
<div>
|
6
|
+
<label for="collection-id"> Collection </label>
|
7
|
+
<select name="collection_id" id="collection-id"><%= options_for_select @collections.insert(0,["Any",""]) %> </select>
|
8
|
+
</div>
|
9
|
+
<div>
|
10
|
+
<label for="admin-set-id"> Administrative Set </label>
|
11
|
+
<select name="admin_set_id" id="admin-set-id"> <%= options_for_select @admin_sets.insert(0,["Any",""]) %> </select>
|
12
|
+
</div>
|
13
|
+
<div>
|
14
|
+
<label for="workflow_state"> Workflow Step </label>
|
15
|
+
<select name="workflow_state" id="workflow-state"> <%= options_for_select @workflow_states.insert(0,["Any",""]) %></select>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div>
|
19
|
+
<label for="keyword"> keyword search </label>
|
20
|
+
<input id="keyword" type="text" name="q" />
|
21
|
+
</div>
|
22
|
+
</form>
|
23
|
+
<button id="add-works-search" type="button"> Search </button>
|
24
|
+
|
25
|
+
<div id="search-summary">
|
26
|
+
<%= form_tag("#{@operation.id}/edit") do %>
|
27
|
+
<div id="draft-search-controls">
|
28
|
+
<div id="all-results" style="display:none">
|
29
|
+
<p id="count"></p>
|
30
|
+
<input type="checkbox" name="add_all_results" id="add-all-results" value="true"/>
|
31
|
+
<label for="add-all-results">Add all search results to update</label>
|
32
|
+
</div>
|
33
|
+
<input type="submit" id="draft-update-add-works" class="show-with-results" value="Add to Update" />
|
34
|
+
</div>
|
35
|
+
<div id="draft-search-display" class="show-with-results">
|
36
|
+
<h4>Sample Results (first 15 results)</h4>
|
37
|
+
<button type="button" class="selections select-all">Select All</button>
|
38
|
+
<button type="button" class="selections select-none">Select None</button>
|
39
|
+
<ul id="search-sample">
|
40
|
+
<li id="template" class="hidden">
|
41
|
+
<input type="checkbox" name="added_work_ids[]" value=""/>
|
42
|
+
<%= image_tag("", height: '200', class: 'work-thumb') %>
|
43
|
+
<div class="work-meta">
|
44
|
+
<div class="work-title"></div>
|
45
|
+
<div class="work-desription"></div>
|
46
|
+
</div>
|
47
|
+
</li>
|
48
|
+
</ul>
|
49
|
+
</div>
|
50
|
+
<input class="prev-search-field" id="prev-collection-id" type="hidden" name="collection_id" value=""/>
|
51
|
+
<input class="prev-search-field" id="prev-admin-set-id" type="hidden" name="admin_set_id" value=""/>
|
52
|
+
<input class="prev-search-field" id="prev-workflow-state" type="hidden" name="workflow_state" value=""/>
|
53
|
+
<input class="prev-search-field" id="prev-keyword" type="hidden" name="keyword" value=""/>
|
54
|
+
<% end %>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
|
58
|
+
</div>
|
59
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div id="update-options" class="options-panel bulk-ops-options">
|
2
|
+
<div>
|
3
|
+
<label for="file-method" data-toggle="tooltip" title="These options determine how the update handles files attached to updated objects. The default option leaves all files alone unless you include a column in your spreadsheet to add or remove specific files.">File Update Method:</label>
|
4
|
+
<select name="file_method" id="file-method">
|
5
|
+
<%= options_for_select @file_update_options, @operation.options['file_method'] || "remove-and-add" %>
|
6
|
+
</select>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
</div>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<% provide :page_title, "List Bulk Operations" %>
|
2
|
+
<%= javascript_include_tag "bulk_ops" %>
|
3
|
+
<%= stylesheet_link_tag "bulk_ops" %>
|
4
|
+
<%= render "bulk_ops_header", title: "Manage Bulk Ingests & Updates" %>
|
5
|
+
<%= render "bulk_ops/github_auth_widget" %>
|
6
|
+
|
7
|
+
<%= form_tag("destroy_multiple") do %>
|
8
|
+
<div id="bulk-ops-index-header">
|
9
|
+
<input type="checkbox" id="bulk-ops-select-all" />
|
10
|
+
<button id="bulk-ops-delete-group">Delete Selected</button>
|
11
|
+
<a href="new" >
|
12
|
+
<button type="button" id="bulk-ops-new"> New Bulk Operation</button>
|
13
|
+
</a>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<ul id="operations-index">
|
17
|
+
<% if @active_operations.empty? %>
|
18
|
+
No bulk operations have been created yet.
|
19
|
+
<% end %>
|
20
|
+
<% @active_operations.each do |operation| %>
|
21
|
+
<li>
|
22
|
+
<input type="checkbox" name="operation_ids[]" class="bulk-ops-index-checkbox" value="<%= operation.id %>" />
|
23
|
+
<div class="op-name">
|
24
|
+
<%= link_to(operation.name,operation)%>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="op-summary">
|
28
|
+
<div class="op-type">
|
29
|
+
<label> Type: </label>
|
30
|
+
<%=operation.type%>
|
31
|
+
</div>
|
32
|
+
<div class="op-stage">
|
33
|
+
<label> Stage: </label>
|
34
|
+
<%=operation.stage%>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<div class="op-status">
|
39
|
+
<label> Status: </label>
|
40
|
+
<%=operation.status%>
|
41
|
+
</label>
|
42
|
+
</div>
|
43
|
+
<div class="op-message">
|
44
|
+
<label> Message: </label>
|
45
|
+
<%=operation.message%>
|
46
|
+
</div>
|
47
|
+
|
48
|
+
</li>
|
49
|
+
<% end %>
|
50
|
+
</ul>
|
51
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<%= javascript_include_tag "bulk_ops" %>
|
2
|
+
<%= stylesheet_link_tag "bulk_ops" %>
|
3
|
+
<% provide :page_title, "New Bulk Operations" %>
|
4
|
+
<%= render "bulk_ops_header", title: 'Create New Bulk Ingest or Update' %>
|
5
|
+
<%= render "bulk_ops/github_auth_widget" %>
|
6
|
+
|
7
|
+
<%= form_tag "/bulk_ops", class: "new-bulk-op", id: "new-bulk-op" do %>
|
8
|
+
|
9
|
+
<div id="operation-name" class="bulk-ops-options">
|
10
|
+
<label data-toggle="tooltip" title="Choose a short descriptive name for this bulk operation" for="bulk-ops-name">New Operation Name:</label>
|
11
|
+
<input type="text" name="name" id="bulk-ops-name" />
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="bulk-ops-options">
|
15
|
+
<label for="op-type" data-toggle="tooltip" title="Would you like to set up a bulk ingest of new works, or a bulk update of existing works?">Ingest or Update?</label>
|
16
|
+
<select name="type" id="op-type" onchange="$('.bulk-ops-options.options-panel').hide();$('#operation-options').show(); $('#'+this.value+'-options').show()" >
|
17
|
+
<option disabled selected value> -- Choose Operation Type -- </option>
|
18
|
+
<option value="ingest">Ingest </option>
|
19
|
+
<option value="update">Update </option>
|
20
|
+
</select>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<%= render "operation_options" %>
|
24
|
+
<%= render "ingest_options" %>
|
25
|
+
<%= render "update_options" %>
|
26
|
+
|
27
|
+
<%= render "choose_fields" %>
|
28
|
+
|
29
|
+
<%= render "choose_notifications" %>
|
30
|
+
|
31
|
+
<%= render "git_message" %>
|
32
|
+
|
33
|
+
<input type="submit" name="create_operation" id="create-operation" value="Create Bulk Operation" />
|
34
|
+
|
35
|
+
<% end %>
|
36
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% provide :page_title, @operation.name.titleize %>
|
2
|
+
<%= javascript_include_tag "embed" %>
|
3
|
+
<%= javascript_include_tag "bulk_ops" %>
|
4
|
+
<%= stylesheet_link_tag "bulk_ops" %>
|
5
|
+
<%= render "bulk_ops_header", title: "Showing Bulk #{@operation.type.capitalize}: #{@operation.name.titleize}" %>
|
6
|
+
|
7
|
+
<%= render "show_#{@operation.stage}"%>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
BulkOps::Engine.routes.draw do
|
2
|
+
|
3
|
+
get 'bulk_ops/authorize/:user_id', to: 'github_authorization#authorize'
|
4
|
+
post 'bulk_ops/github_logout/:user_id', to: 'github_authorization#logout'
|
5
|
+
post 'bulk_ops/apply', to: 'operations#apply'
|
6
|
+
|
7
|
+
resources :operations, path: :bulk_ops do
|
8
|
+
|
9
|
+
collection do
|
10
|
+
get :search
|
11
|
+
post :apply
|
12
|
+
post :search
|
13
|
+
post :destroy_multiple
|
14
|
+
end
|
15
|
+
|
16
|
+
member do
|
17
|
+
get :csv
|
18
|
+
post :request_apply
|
19
|
+
post :approve
|
20
|
+
post :edit
|
21
|
+
post :duplicate
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateGithubCredentials < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :bulk_ops_github_credentials do |t|
|
4
|
+
t.integer :user_id
|
5
|
+
t.string :username
|
6
|
+
t.string :oauth_token
|
7
|
+
t.string :state
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
add_index :bulk_ops_github_credentials, :user_id
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class CreateBulkOpsTables < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
|
4
|
+
create_table :bulk_ops_operations do |t|
|
5
|
+
t.references :user, foreign_key: true
|
6
|
+
t.string :name, null: false, unique: true
|
7
|
+
t.string :stage, null: false
|
8
|
+
t.string :operation_type
|
9
|
+
t.string :commit_sha
|
10
|
+
t.integer :pull_id
|
11
|
+
t.string :status
|
12
|
+
t.text :message
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :bulk_ops_work_proxies do |t|
|
17
|
+
t.integer :operation_id
|
18
|
+
t.string :work_id
|
19
|
+
t.integer :row_number
|
20
|
+
t.datetime :last_event
|
21
|
+
t.string :status
|
22
|
+
t.text :message
|
23
|
+
t.string :visibility
|
24
|
+
t.string :work_type
|
25
|
+
t.string :reference_identifier
|
26
|
+
t.string :order
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :bulk_ops_relationships do |t|
|
31
|
+
t.integer :work_proxy_id
|
32
|
+
t.string :object_identifier
|
33
|
+
t.string :identifier_type
|
34
|
+
t.string :relationship_type
|
35
|
+
t.string :status
|
36
|
+
t.timestamps
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/bulk_ops.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bulk_ops/version"
|
2
|
+
|
3
|
+
module BulkOps
|
4
|
+
dirstring = File.join( File.dirname(__FILE__), 'bulk_ops/**/*.rb')
|
5
|
+
Dir[dirstring].each do |file|
|
6
|
+
begin
|
7
|
+
require file
|
8
|
+
rescue Exception => e
|
9
|
+
puts "ERROR LOADING #{File.basename(file)}: #{e}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
# require 'bulk_ops/verification'
|
13
|
+
# require 'bulk_ops/verification'
|
14
|
+
# require 'bulk_ops/work_proxy'
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class BulkOps::CreateSpreadsheetJob < ActiveJob::Base
|
2
|
+
|
3
|
+
queue_as :default
|
4
|
+
|
5
|
+
def perform(branch_name, work_ids, fields, user)
|
6
|
+
csv_file = Tempfile.new('bulk_ops_metadata')
|
7
|
+
csv_file.write(fields.join(','))
|
8
|
+
work_ids.each do |work_id|
|
9
|
+
if work_csv = work_to_csv(work_id,fields)
|
10
|
+
csv_file.write("\r\n" + work_csv)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
csv_file.close
|
14
|
+
BulkOps::GithubAccess.new(branch_name, user).add_new_spreadsheet(csv_file.path)
|
15
|
+
csv_file.unlink
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def work_to_csv work_id, fields
|
21
|
+
return false if work_id.empty?
|
22
|
+
begin
|
23
|
+
work = Work.find(work_id)
|
24
|
+
rescue ActiveFedora::ObjectNotFoundError
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
line = ''
|
28
|
+
fields.map do |field_name|
|
29
|
+
label = false
|
30
|
+
if field_name.downcase.include? "label"
|
31
|
+
label = true
|
32
|
+
field_name = field_name[0..-7]
|
33
|
+
end
|
34
|
+
values = work.send(field_name)
|
35
|
+
values.map do |value|
|
36
|
+
next if value.is_a? DateTime
|
37
|
+
value = (label ? WorkIndexer.fetch_remote_label(value.id) : value.id) unless value.is_a? String
|
38
|
+
value.gsub("\"","\"\"")
|
39
|
+
end.join(BulkOps::WorkProxy::SEPARATOR).prepend('"').concat('"')
|
40
|
+
end.join(',')
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#require 'hydra/access_controls'
|
2
|
+
#require 'hyrax/workflow/activate_object'
|
3
|
+
|
4
|
+
class BulkOps::DeleteFileSetJob < ActiveJob::Base
|
5
|
+
|
6
|
+
queue_as :ingest
|
7
|
+
|
8
|
+
def perform(file_set_id,user_email)
|
9
|
+
user = User.find_by_email(user_email)
|
10
|
+
Hyrax::Actors::FileSetActor.new(@file_set, user).destroy
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class BulkOps::Error
|
2
|
+
attr_accessor :type, :row_number, :object_id, :message, :option_name, :file, :option_values, :field, :url
|
3
|
+
|
4
|
+
MAX_ERROR = 50
|
5
|
+
|
6
|
+
def initialize type:, row_number: nil, object_id: nil, message: nil, options_name: nil, option_values: nil, field: nil, url: nil , file: nil
|
7
|
+
@type = type
|
8
|
+
@row_number = row_number
|
9
|
+
@object_id = object_id
|
10
|
+
@message = message
|
11
|
+
@option_name = option_name
|
12
|
+
@option_values = option_values
|
13
|
+
@field = field
|
14
|
+
@file = file
|
15
|
+
@url = url
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.write_errors! errors, git
|
19
|
+
return false if errors.blank?
|
20
|
+
error_file_name = "error_log_#{DateTime.now.strftime("%F-%H%M%p")}.log"
|
21
|
+
|
22
|
+
error_hash = {}
|
23
|
+
|
24
|
+
errors.sort!{|x,y| x.type <=> y.type}
|
25
|
+
error_types = errors.map{|error| error.type}.uniq
|
26
|
+
|
27
|
+
#write errors to error file
|
28
|
+
error_file = Tempfile.new(error_file_name)
|
29
|
+
error_types.each do |error_type|
|
30
|
+
typed_errors = errors.select{|er| er.type == error_type}
|
31
|
+
next if typed_errors.blank?
|
32
|
+
message = self.error_message(error_type, typed_errors)
|
33
|
+
puts "Error message: #{message}"
|
34
|
+
error_file.write(message)
|
35
|
+
end
|
36
|
+
error_file.close
|
37
|
+
git.add_file error_file.path, File.join("errors", error_file_name)
|
38
|
+
error_file.unlink
|
39
|
+
return error_file_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.error_message type, errors
|
43
|
+
case type
|
44
|
+
when :mismatched_auth_terms
|
45
|
+
message = "\n-- Controlled Authority IDs and Labels don't match -- \n"
|
46
|
+
message += "The operation is set to create an error if the provided URLs for controlled authority terms do not resolve to the provided labels.\n"
|
47
|
+
if errors.count < MAX_ERROR
|
48
|
+
message += "The following rows were affected:\n"
|
49
|
+
message += errors.map{|error| error.row_number}.join(",")+"\n"
|
50
|
+
else
|
51
|
+
message += "#{errors.count} rows were affected. An example is row # #{errors.first.row_number}.\n"
|
52
|
+
end
|
53
|
+
when :upload_error
|
54
|
+
message = "\n-- Errors uploading files -- \n"
|
55
|
+
message += "Your files looked ok when we checked earlier, but we couldn't access them when we were trying to actually start the operation.\n"
|
56
|
+
if errors.count < MAX_ERROR
|
57
|
+
message += "The following files were affected:\n"
|
58
|
+
message += errors.map{|error| "Row #{row_number}, Filename: #{error.file}"}.join("\n")+"\n"
|
59
|
+
else
|
60
|
+
message += "#{errors.count} rows were affected. An example is row # #{errors.first.row_number} with file #{errors.first.file}.\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
when :no_work_id_field
|
64
|
+
message = "\n-- Cannot find work id field in spreadsheet -- \n"
|
65
|
+
message += "We were trying to start your operation, but could find find the work id for #{errors.count} different rows of the spreadsheet.\n"
|
66
|
+
message += "Check your spreadsheet and try again.\n"
|
67
|
+
message += errors.map{|arg| " #{error.object_id || 'new work'}: #{error.message}"}.join("\n") + "\n"
|
68
|
+
when :job_failure
|
69
|
+
message = "\n-- Jobs Failed -- \n:"
|
70
|
+
message += errors.map{|arg| "Error message operating on #{error.object_id || 'new work'}: #{error.message}"}.join("\n") + "\n"
|
71
|
+
when :missing_required_option
|
72
|
+
message = "\n-- Errors in configuration file -- \nMissing required option(s):"
|
73
|
+
message += errors.map{|arg| error.option_name}.join(", ") + "\n"
|
74
|
+
|
75
|
+
when :invalid_config_value
|
76
|
+
message = "\n-- Errors in configuration file values --\n"
|
77
|
+
errors.each do |error|
|
78
|
+
message += "Unacceptable value for #{error.option_name}. Acceptable values include: #{error.option_values}\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
when :cannot_get_headers
|
82
|
+
message += "\n-- Error Retrieving Field Headers --\n"
|
83
|
+
message += "We cannot retrieve the column headers from metadata spreadsheet on github,\nwhich define the fields for the metadata below.\nEither the connection to github is failing, \nor the metadata spreadsheet on this branch is not properly formatted.\n"
|
84
|
+
|
85
|
+
when :bad_header
|
86
|
+
message = "\n-- Error interpreting column header(s) --\n"
|
87
|
+
message += "We cannot interpret all of the headers from your metadata spreadsheet. \nSpecifically, the following headers did not make sense to us:\n"
|
88
|
+
message += errors.map{|error| error.field}.join(", ")+"\n"
|
89
|
+
|
90
|
+
when :cannot_retrieve_label
|
91
|
+
message = "\n-- Errors Retrieving Remote Labels --\n"
|
92
|
+
urls = errors.map{|error| error.url}.uniq
|
93
|
+
if urls.count < MAX_ERROR
|
94
|
+
urls.each do |url|
|
95
|
+
url_errors = errors.select{|er| er.url == url}
|
96
|
+
message += "Error retrieving label for remote url #{url}. \nThis url appears in #{url_errors.count} instances in the spreadsheet.\n"
|
97
|
+
message += "The affected rows are listed here:\n"
|
98
|
+
message += url_errors.map{|er| er.row_number}.compact.join('\n')+"\n"
|
99
|
+
end
|
100
|
+
else
|
101
|
+
message += "There were #{urls.count} different URLs in the spreadsheet that we couldn't retrieve labels for,\n making a total of #{errors.count} url related errors.\n These are too many to list, but an example is #{errors.first.url}\n in row #{errors.first.row_number}.\n"
|
102
|
+
end
|
103
|
+
|
104
|
+
when :cannot_retrieve_url
|
105
|
+
message = "\n-- Errors Retrieving Remote URLs --\n"
|
106
|
+
urls = errors.map{|error| error.url}.uniq
|
107
|
+
if urls.count < MAX_ERROR
|
108
|
+
urls.each do |url|
|
109
|
+
url_errors = errors.select{|er| er.url == url}
|
110
|
+
message += "Error retrieving URL for remote authority term #{url}. \nThis term appears in #{url_errors.count} instances in the spreadsheet.\n"
|
111
|
+
message += "The affected rows are listed here:\n"
|
112
|
+
message += url_errors.map{|er| er.row_number}.compact.join('\n')+"\n"
|
113
|
+
end
|
114
|
+
else
|
115
|
+
message += "There were #{urls.count} different controlled vocab terms in the spreadsheet that we couldn't retrieve or create URLs for,\n making a total of #{errors.count} controlled term related errors.\n These are too many to list, but an example is #{errors.first.url}\n in row #{errors.first.row_number}.\n"
|
116
|
+
end
|
117
|
+
|
118
|
+
when :bad_object_reference
|
119
|
+
message = "\n-- Error: bad object reference --\m"
|
120
|
+
message += "We enountered #{errors.count} problems resolving object references.\n"
|
121
|
+
if errors.count < MAX_ERROR
|
122
|
+
message += "The row numbers with problems were:\n"
|
123
|
+
message += errors.map{|er| "row number #{er.row_number} references the object #{er.object_id}"}.join("\n")
|
124
|
+
else
|
125
|
+
message += "For example, row number #{errors.first.row_number} references an object identified by #{errors.first.object_id}, which we cannot find."
|
126
|
+
end
|
127
|
+
|
128
|
+
when :cannot_find_file
|
129
|
+
message = "\n-- Missing File Errors --\n "
|
130
|
+
message += "We couldn't find the files listed on #{errors.count} rows.\n"
|
131
|
+
if errors.count < MAX_ERROR
|
132
|
+
message += "Missing filenames:\n"
|
133
|
+
message += errors.map{|er| er.file}.join("\n")
|
134
|
+
else
|
135
|
+
message += "An example of a missing filename is: #{errors.first.file}\n"
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
return message
|
140
|
+
end
|
141
|
+
end
|