cdm_migrator 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
-