cdm_migrator 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdf5a7cb1cb95ce144dd931ed6b309ebc20d5f93ee8e91e6cfbabafded6a35fb
4
- data.tar.gz: 6594d9da22ee42db51c96ac5393289b210c5b60e2e0a3066aa8f5e3571d6987e
3
+ metadata.gz: 330afa0ea8f2de397dc822fafef651778e039b0b422ec8ab93e61bd4ed6e9ced
4
+ data.tar.gz: 6860866888bf49430fbbb4eace6e38bb7b2da09f6b8633608e7508cac374dc4c
5
5
  SHA512:
6
- metadata.gz: 2798dd9b01e019d298cf007604fbb54105856e1761eb7d5cca62b7bd1d1f4587b4b48b0d43e9881ffb0a01ebf8d4a27b7b3469d83a68c265353368ebca4b2489
7
- data.tar.gz: 0ab6fa9e3a5324fb0c80692cdcda02aee0fb18dd0b0d20a570789e3478292987a91101cbd86e362d929c56d197af6ed20f82372d2b275ecd69f1f4a5dda3f076
6
+ metadata.gz: f263a7da82234a60ac6ac4f73529b226762b483dee9ce093712f8dd3c34dc97b3b1b96b5b62cbc98d0de5f2dc1157367b5c1352a5cb79bd7703f45a707ceb034
7
+ data.tar.gz: f4f095574c88c63970d2de9032ad96ad134ff34952b78068a2ddceee404d9998134ccfac15ee29ca75d2ac9c7b8f4a3a4db33030b6218d8b100afa64ea357cd3
data/README.md CHANGED
@@ -27,11 +27,12 @@ to insert the yml and add a link to your Hyrax dashboard
27
27
 
28
28
  ## Usage
29
29
  1. Add your ContentDM url and api port to the cdm_migrator.yml file.
30
- 2. Navigate to the *cdm_migrator/collection* url to select your contentdm collection and what type of work you want to export it to and click "choose mappings".
31
- 3. Map the ContentDM fields to your Hyrax work and file fields\* and click "generate CSV".
32
- 4. Refine the CSV as you see fit.
33
- 5. Navigate to the *cdm_migrator/upload* url; choose your multi-value seperator (default is |) and upload your CSV file.
34
- 6. Done.
30
+ 2. Configure the CSV Checker with the appropriate fields, paths, or multi-value separator (in cdm_migrator.yml).
31
+ 3. Navigate to the *cdm_migrator/collection* url to select your contentdm collection and what type of work you want to export it to and click "choose mappings".
32
+ 4. Map the ContentDM fields to your Hyrax work and file fields\* and click "generate CSV".
33
+ 5. Refine the CSV as you see fit. Optional: go to *cdm_migrator/csv_checker* and upload it to validate metadata fields and/or file paths.
34
+ 6. Navigate to the *cdm_migrator/upload* url; choose your multi-value separator (default is |) and upload your CSV file.
35
+ 7. Done.
35
36
 
36
37
  \* cdm_migrator uses the generated Hyrax forms (ex. Hyrax::Forms::GenericWorkForm) in your host application to obtain it's terms for mapping. If you have added terms to your FileSet model extend the Hyrax::Forms::FileSetEditForm with Hyrax::FileSetForm in your host application so that the changes will be detected by the migrator. You can also add a list of fields in the yml file, under "default fields".
37
38
 
@@ -0,0 +1,37 @@
1
+ .csv-collapse-link.collapsed {
2
+ display: inline-block;
3
+ vertical-align: top;
4
+ }
5
+
6
+ #csv-collapse-link-text::after {
7
+ content: "❯";
8
+ display: inline-block;
9
+ font-size: smaller;
10
+ right: 15px;
11
+ transform: rotate(90deg);
12
+ margin-left: 0.5em;
13
+ }
14
+
15
+ .collapsed #csv-collapse-link-text::after {
16
+ transform: rotate(0deg);
17
+ transition: transform 0.1s ease;
18
+ margin-left: 2px;
19
+ vertical-align: top;
20
+ }
21
+
22
+ #errors-explanation ul li {
23
+ list-style-type: none;
24
+ margin-bottom: 2px;
25
+ }
26
+
27
+ #errors-explanation ul {
28
+ padding-left: 0;
29
+ }
30
+
31
+ #errors-explanation {
32
+ margin-top: 5px;
33
+ }
34
+
35
+ #csv-form {
36
+ margin-top: 1em;
37
+ }
@@ -104,10 +104,10 @@ module CdmMigrator
104
104
 
105
105
  def load_yaml
106
106
  stripped_url = request.base_url.dup.gsub(/https?:\/\//, '').gsub(/:[0-9]*/,'')
107
- if CdmMigrator::Engine.config['cdm_api'].key? stripped_url
108
- tenant = CdmMigrator::Engine.config['cdm_api'][stripped_url]
107
+ if CdmMigrator::Engine.config['tenant_settings'].key? stripped_url
108
+ tenant = CdmMigrator::Engine.config['tenant_settings'][stripped_url]['cdm_api']
109
109
  else
110
- tenant = CdmMigrator::Engine.config['cdm_api']['default']
110
+ tenant = CdmMigrator::Engine.config['tenant_settings']['default']['cdm_api']
111
111
  end
112
112
  @cdm_url = tenant['url']
113
113
  @cdm_port = tenant['port']
@@ -4,15 +4,15 @@ module CdmMigrator
4
4
  include ActionView::Helpers::UrlHelper
5
5
  layout 'hyrax/dashboard' if Hyrax
6
6
  before_action :authenticate, except: :index
7
+ before_action :load_config, only: :csv_checker
7
8
 
8
- def file_path_checker
9
+ def csv_checker
9
10
  if params[:file]
10
- check_paths params[:file].path
11
-
12
- if @path_list.blank?
13
- flash[:notice] = "All file paths are valid."
11
+ check_csv params[:file].path
12
+ if @error_list.blank?
13
+ flash[:notice] = "All data are valid."
14
14
  else
15
- flash[:error] = "Cdm Migrator couldn't find files at the following urls. Please correct the paths and try again."
15
+ flash[:error] = "The CSV Checker found some errors in the CSV. Please correct them and check again."
16
16
  end
17
17
  end
18
18
  end
@@ -41,9 +41,9 @@ module CdmMigrator
41
41
  File.open(csv, 'wb') do |file|
42
42
  file.write(params[:csv_import][:csv_file].read)
43
43
  end
44
- check_paths csv
45
- if @path_list.present?
46
- flash[:error] = "some file paths are invalid"
44
+ check_csv csv
45
+ if @error_list.present?
46
+ flash[:error] = "Cdm Migrator found some problems with the CSV. Use the CSV Checker for more details."
47
47
  end
48
48
  parse_csv(csv, params[:csv_import][:mvs])
49
49
 
@@ -203,19 +203,104 @@ module CdmMigrator
203
203
  end
204
204
  end
205
205
 
206
- def check_paths csv_file
207
- row_number = 1 # +1 offset to account for csv headers
208
- @path_list = {}
206
+ def load_config
207
+ tenant = Account.find_by(tenant: Apartment::Tenant.current).cname
208
+ if CdmMigrator::Engine.config['tenant_settings'].has_key?(tenant)
209
+ settings = CdmMigrator::Engine.config['tenant_settings'][tenant]['csv_checker']
210
+ if settings.present?
211
+ # .map will throw an error if settings[key] has no value
212
+ @edtf_fields = settings['edtf_fields'].map(&:to_sym) if settings['edtf_fields']
213
+ @uri_fields = settings['valid_uri_fields'].map(&:to_sym) if settings['valid_uri_fields']
214
+ @separator = settings['multi_value_separator']
215
+ @separator_fields = settings['separator_fields'].map(&:to_sym) if settings['separator_fields']
216
+ @path_to_drive = settings['path_to_drive']
217
+ else
218
+ raise "Cdm Migrator couldn't find any configured settings. Are they in cdm_migrator.yml?"
219
+ end
220
+ else
221
+ raise "Cdm Migrator couldn't find this tenant. Is it configured?"
222
+ end
223
+ end
224
+
225
+ def check_csv csv_file
226
+ row_number = 1
227
+ @error_list = {}
228
+ check_mounted_drive if @path_to_drive.present?
229
+
230
+ CSV.foreach(csv_file, headers: true, header_converters: :symbol) do |row|
231
+ row_number +=1 # Tells user what CSV row the error is on
232
+ if row[:object_type].include? "Work"
233
+ check_edtf(row_number, row) if @edtf_fields.present?
234
+ check_uris(row_number, row) if @uri_fields.present?
235
+ if params[:multi_value_separator].present? and @separator_fields.present?
236
+ check_separator(row_number, row, params[:multi_value_separator])
237
+ else
238
+ alert_message = "No multi-value separator character was selected or no fields were configured. CSV Checker didn't check for valid separators."
239
+ if flash[:alert] and flash[:alert].exclude?(alert_message) # Only add this message once, rather than per line
240
+ flash[:alert] << alert_message
241
+ elsif flash[:alert].blank?
242
+ flash[:alert] = Array.wrap(alert_message)
243
+ end
244
+ end
245
+ elsif row[:object_type] == "File"
246
+ check_file_path(row_number, row[:url])
247
+ else
248
+ @error_list[row_number] = { "object_type" => "No or unknown object type. Please give a valid type (e.g. GenericWork, File)." }
249
+ end
250
+ @error_list.delete_if { |key, value| value.blank? } # Data are valid, no need to print the row
251
+ end
252
+ end
253
+
254
+ def check_mounted_drive
255
+ drive_address = @path_to_drive
256
+ unless Dir.exist?(drive_address) and !Dir[drive_address].empty?
257
+ flash[:alert] = "CSV Checker can't find the mounted drive to check file paths, so some paths may be mislabelled as incorrect. Please contact the administrator or try again later."
258
+ end
259
+ end
260
+
261
+ def check_file_path(row_number, file_path)
262
+ if file_path.nil?
263
+ @error_list[row_number] = { "url" => "url is blank." }
264
+ elsif File.file?(file_path.gsub("file://", "")) == false
265
+ @error_list[row_number] = { "url" => "No file found at #{file_path}" }
266
+ end
267
+ end
268
+
269
+ def check_edtf(row_number, row)
270
+ edtf_fields = @edtf_fields
271
+ edtf_errors = edtf_fields.each_with_object({}) do |field, hash|
272
+ if Date.edtf(row[field]) == nil and row[field] != "unknown"
273
+ hash[field.to_s] = "Blank or not a valid EDTF date."
274
+ end
275
+ end
276
+ @error_list[row_number] = edtf_errors
277
+ end
278
+
279
+ # <Example: should be http://rightsstatements.org/vocab/etc. NOT https://rightsstatements.org/page/etc.
280
+ def check_uris(row_number, row)
281
+ uri_fields = @uri_fields
282
+ uri_errors = uri_fields.each_with_object({}) do |field, hash|
283
+ if row[field].include? "page"
284
+ hash[field.to_s] = "Links to page instead of URI. (e.g. https://rightsstatements.org/page/etc. instead of http://rightsstatements.org/vocab/etc.)"
285
+ end
286
+ end
287
+ @error_list[row_number].merge!(uri_errors)
288
+ end
209
289
 
210
- CSV.foreach(csv_file, headers: true, header_converters: :symbol) do |row|
211
- row_number += 1 # Tells user what CSV row the bogus file path is on
212
- next if row[:url].nil?
213
- file_path = row[:url]
214
- unless File.file?(file_path.gsub("file://", ""))
215
- @path_list[row_number] = file_path
290
+ # Check multi-value separators
291
+ def check_separator(row_number, row, character)
292
+ uri_fields = @separator_fields
293
+ separator_errors = uri_fields.each_with_object({}) do |field, hash|
294
+ value = row[field]
295
+ if value.present?
296
+ URI.extract(value).each { |uri| value.gsub!(uri, '') }
297
+ unless value.split("").all?(character) # Check if remaining characters are the correct separator
298
+ hash[field.to_s] = "May contain the wrong multi-value separator (i.e. not #{character})."
216
299
  end
217
300
  end
218
301
  end
302
+ @error_list[row_number].merge!(separator_errors)
303
+ end
219
304
 
220
305
  def default_page_title
221
306
  'CSV Batch Uploader'
@@ -9,6 +9,12 @@ module CdmMigrator
9
9
  #status_after, embargo_date, lease_date = nil, nil, nil
10
10
  work.apply_depositor_metadata(user)
11
11
  work.attributes = ingest_work.data
12
+ if ingest_work.data.has_key? 'downloadable'
13
+ # Convert string to boolean
14
+ work.downloadable = ActiveModel::Type::Boolean.new.cast(ingest_work.data['downloadable'])
15
+ elsif work.attributes.include? 'downloadable' # Set work to downloadable by default
16
+ work.downloadable = true
17
+ end
12
18
  work.member_of_collections = [collection] if collection
13
19
  work.admin_set = admin_set if admin_set
14
20
  work.date_uploaded = DateTime.now
@@ -0,0 +1,46 @@
1
+ <% provide :page_title, "CSV Checker" %>
2
+
3
+ <%#= flash[:alert].join("<br/>") if flash[:alert] %>
4
+
5
+ <h1>CSV Checker</h1>
6
+
7
+ <!-- <div class="row"> -->
8
+ <p>This tool validates CSV data and creates a table listing any errors.</p>
9
+
10
+ <a role="button" class="collapse-toggle collapsed csv-collapse-link" data-toggle="collapse" data-target="#errors-explanation" aria-expanded="false">
11
+ <span id="csv-collapse-link-text">Expand for more details</span>
12
+ </a>
13
+ <div class="collapse" id="errors-explanation">
14
+ <ul>
15
+ <li><strong>File paths: </strong>The url field contains a valid path to a file.</li>
16
+ <li><strong>Multi-value separator: </strong>Configured fields with URIs contain the right separator character (e.g. |).</li>
17
+ <% if @path_to_drive.present? %>
18
+ <li><strong>Mounted drive: </strong>A mounted directory (folder) exists and is not empty.</li>
19
+ <% end %>
20
+ <% if @edtf_fields.present? %>
21
+ <li><strong>EDTF dates: </strong>Configured fields contain valid <a href="https://www.loc.gov/standards/datetime/" target="_blank">EDTF</a> dates or "unknown."</li>
22
+ <% end %>
23
+ <% if @uri_fields.present? %>
24
+ <li><strong>Valid URIs ("page" vs "vocab"): </strong>Configured fields with URIs link to the "vocab" address rather than the "page" address. For example, rights_statement should be "http://rightsstatement.org/vocab/..." and not "https://rightsstatement.org/page/..."</li>
25
+ <% end %>
26
+ </ul>
27
+ </div>
28
+
29
+
30
+
31
+ <%= form_tag(check_csv_path, remote: true, method: :post, multipart: true, id: "csv-form") do %>
32
+ <div class="input-group">
33
+ <%= label_tag :multi_value_separator %>
34
+ <%= text_field_tag(:multi_value_separator, @separator, size: 1) %>
35
+ <%= file_field_tag(:file, class: "form-control-file") %>
36
+ <%= hidden_field_tag :authenticity_token, value: form_authenticity_token %>
37
+ <%= button_tag(type: :submit, class: "btn btn-large btn-primary", style: "margin-top: 1em;") do %>
38
+ Check CSV
39
+ <% end %>
40
+ <% end %>
41
+ </div>
42
+ <!-- </div> -->
43
+
44
+ <div id="error_list" class="col-md-10 offset-md-1">
45
+ <%= render 'error_list' %>
46
+ </div>
@@ -9,8 +9,8 @@ Rails.application.routes.draw do
9
9
  post '/cdm_migrator/export', to: 'cdm_migrator/csv#export', as: 'csv_export'
10
10
  post '/cdm_migrator/update', to: 'cdm_migrator/csv#update', as: 'csv_update'
11
11
 
12
- get '/cdm_migrator/file_path_checker', to: 'cdm_migrator/csv#file_path_checker', as: 'file_path_checker'
13
- post '/cdm_migrator/file_path_checker', to: 'cdm_migrator/csv#file_path_checker', as: 'check_file_paths'
12
+ get '/cdm_migrator/csv_checker', to: 'cdm_migrator/csv#csv_checker', as: 'csv_checker'
13
+ post '/cdm_migrator/csv_checker', to: 'cdm_migrator/csv#csv_checker', as: 'check_csv'
14
14
 
15
15
  get '/cdm_migrator/collection', to: 'cdm_migrator/cdm#collection', as: 'cdm_start'
16
16
  post '/cdm_migrator/mappings/', to: 'cdm_migrator/cdm#mappings', as: 'cdm_mappings'
@@ -1,3 +1,3 @@
1
1
  module CdmMigrator
2
- VERSION = '3.1.0'
2
+ VERSION = '3.2.0'
3
3
  end
@@ -22,8 +22,8 @@ class CdmMigrator::InstallGenerator < Rails::Generators::Base
22
22
  " <%= menu.nav_link(main_app.cdm_start_path) do %>\n" \
23
23
  " <span class=\"fa fa-map\"></span> <span class=\"sidebar-action-text\"><%= t('CDM Mapping Tool') %></span>\n" \
24
24
  " <% end %>\n" \
25
- " <%= menu.nav_link(main_app.file_path_checker_path) do %>\n" \
26
- " <span class=\"fa fa-check-circle\"></span><span>File Path Checker</span>\n" \
25
+ " <%= menu.nav_link(main_app.csv_checker_path) do %>\n" \
26
+ " <span class=\"fa fa-check-circle\"></span><span>CSV Checker</span>\n" \
27
27
  " <% end %>\n" \
28
28
  " <%= menu.nav_link(main_app.csv_upload_path) do %>\n"\
29
29
  " <span class=\"fa fa-angle-double-up\"></span> <span class=\"sidebar-action-text\"><%= t('CSV Batch Uploader') %></span>\n" \
@@ -67,5 +67,13 @@ class CdmMigrator::InstallGenerator < Rails::Generators::Base
67
67
  def inject_content_dm_yml
68
68
  copy_file("config/cdm_migrator.yml", "config/cdm_migrator.yml") unless File.file?("config/cdm_migrator.yml")
69
69
  end
70
+
71
+ def inject_stylesheets
72
+ css_file_path = "app/assets/stylesheets/application.css"
73
+ copy_file("stylesheets/csv_checker.css", "app/assets/stylesheets/csv_checker.css") unless File.file?("app/assets/styelsheets/csv_checker.css")
74
+ insert_into_file css_file_path, :before => " *= require_self\n" do
75
+ " *= require csv_checker\n "
76
+ end
77
+ end
70
78
 
71
79
  end
@@ -1,25 +1,38 @@
1
- cdm_api:
1
+ tenant_settings:
2
2
  tenant1.institution.com:
3
- url: 'http://your-content-dm-host'
4
- port: 8080
5
- type: 'front'
6
- dirs:
7
- dir1: '/dir1/path/goes/here'
8
- dir2: '/dir2/path/goes/here'
3
+ cdm_api:
4
+ url: 'http://your-content-dm-host'
5
+ port: 8080
6
+ type: 'front'
7
+ dirs:
8
+ dir1: '/dir1/path/goes/here'
9
+ dir2: '/dir2/path/goes/here'
9
10
  tenant2.institution.com:
10
- url: 'http://your-content-dm-host'
11
- port: 8080
12
- type: 'front'
13
- dirs:
14
- dir1: '/dir1/path/goes/here'
15
- dir2: '/dir2/path/goes/here'
11
+ cdm_api:
12
+ url: 'http://your-content-dm-host'
13
+ port: 8080
14
+ type: 'front'
15
+ dirs:
16
+ dir1: '/dir1/path/goes/here'
17
+ dir2: '/dir2/path/goes/here'
16
18
  default:
17
- url: 'http://your-content-dm-host'
18
- port: 8080
19
- type: 'front'
20
- dirs:
21
- dir1: '/dir1/path/goes/here'
22
- dir2: '/dir2/path/goes/here'
19
+ cdm_api:
20
+ url: 'http://your-content-dm-host'
21
+ port: 8080
22
+ type: 'front'
23
+ dirs:
24
+ dir1: '/dir1/path/goes/here'
25
+ dir2: '/dir2/path/goes/here'
26
+ csv_checker:
27
+ edtf_fields:
28
+ # - date_created
29
+ valid_uri_fields:
30
+ # - rights_statement
31
+ # - genre
32
+ separator_fields:
33
+ # - subject
34
+ multi_value_separator: # '|'
35
+ path_to_drive: #'/mnt/drive'
23
36
  default_fields:
24
37
  - title
25
38
  - creator
@@ -8,8 +8,8 @@
8
8
  <span class="fa fa-map"></span> <span class="sidebar-action-text"><%= t('CDM Mapping Tool') %></span>
9
9
  <% end %>
10
10
 
11
- <%= menu.nav_link(main_app.file_path_checker_path) do %>
12
- <span class="fa fa-check-circle"></span><span class="sidebar-action-text"><%= t('File Path Checker') %></span>
11
+ <%= menu.nav_link(main_app.csv_checker_path) do %>
12
+ <span class="fa fa-check-circle"></span><span class="sidebar-action-text"><%= t('CSV Checker') %></span>
13
13
  <% end %>
14
14
 
15
15
  <%= menu.nav_link(main_app.csv_upload_path) do %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cdm_migrator
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sephirothkod
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-19 00:00:00.000000000 Z
11
+ date: 2020-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -81,6 +81,7 @@ files:
81
81
  - app/assets/config/cdm_migrator_manifest.js
82
82
  - app/assets/javascripts/cdm_migrator/application.js
83
83
  - app/assets/stylesheets/cdm_migrator/application.css
84
+ - app/assets/stylesheets/cdm_migrator/csv_checker.css
84
85
  - app/controllers/cdm_migrator/application_controller.rb
85
86
  - app/controllers/cdm_migrator/cdm_controller.rb
86
87
  - app/controllers/cdm_migrator/csv_controller.rb
@@ -103,8 +104,8 @@ files:
103
104
  - app/views/cdm_migrator/csv/_path_list.html.erb
104
105
  - app/views/cdm_migrator/csv/_results_pagination.html.erb
105
106
  - app/views/cdm_migrator/csv/_tabs.html.erb
107
+ - app/views/cdm_migrator/csv/csv_checker.html.erb
106
108
  - app/views/cdm_migrator/csv/edit.html.erb
107
- - app/views/cdm_migrator/csv/file_path_checker.html.erb
108
109
  - app/views/cdm_migrator/csv/index.html.erb
109
110
  - app/views/cdm_migrator/csv/upload.html.erb
110
111
  - app/views/layouts/cdm_migrator/application.html.erb
@@ -1,21 +0,0 @@
1
- <% provide :page_title, "File Path Checker" %>
2
-
3
- <h1>File Path Checker</h1>
4
-
5
- <!-- <div class="row"> -->
6
- <p>This tool checks if a file exists at each url in a csv.</p>
7
- <%= form_tag(check_file_paths_path, remote: true, method: :post, multipart: true, id: "csv-form") do %>
8
- <div class="input-group">
9
- <%= file_field_tag(:file, class: "form-control-file") %>
10
- <%= hidden_field_tag :authenticity_token, value: form_authenticity_token %>
11
- <%= button_tag(type: :submit, class: "btn btn-large btn-primary", style: "margin-top: 1em;") do %>
12
- Check CSV
13
- <% end %>
14
- <% end %>
15
- </div>
16
- <!-- </div> -->
17
-
18
- <div id="path_list" class="col-md-10 offset-md-1">
19
- <%= render 'path_list' %>
20
- </div>
21
-