bulkrax 1.0.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.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +205 -0
  3. data/README.md +202 -0
  4. data/Rakefile +42 -0
  5. data/app/assets/config/bulkrax_manifest.js +2 -0
  6. data/app/assets/javascripts/bulkrax/application.js +14 -0
  7. data/app/assets/javascripts/bulkrax/bulkrax.js +11 -0
  8. data/app/assets/javascripts/bulkrax/entries.js +15 -0
  9. data/app/assets/javascripts/bulkrax/exporters.js +60 -0
  10. data/app/assets/javascripts/bulkrax/importers.js.erb +166 -0
  11. data/app/assets/stylesheets/bulkrax/accordion.scss +40 -0
  12. data/app/assets/stylesheets/bulkrax/application.css +15 -0
  13. data/app/assets/stylesheets/bulkrax/coderay.scss +264 -0
  14. data/app/assets/stylesheets/bulkrax/import_export.scss +37 -0
  15. data/app/controllers/bulkrax/application_controller.rb +8 -0
  16. data/app/controllers/bulkrax/entries_controller.rb +44 -0
  17. data/app/controllers/bulkrax/exporters_controller.rb +125 -0
  18. data/app/controllers/bulkrax/importers_controller.rb +315 -0
  19. data/app/controllers/concerns/bulkrax/api.rb +29 -0
  20. data/app/factories/bulkrax/object_factory.rb +230 -0
  21. data/app/helpers/bulkrax/application_helper.rb +15 -0
  22. data/app/helpers/bulkrax/exporters_helper.rb +6 -0
  23. data/app/helpers/bulkrax/importers_helper.rb +13 -0
  24. data/app/helpers/bulkrax/validation_helper.rb +153 -0
  25. data/app/jobs/bulkrax/application_job.rb +6 -0
  26. data/app/jobs/bulkrax/child_relationships_job.rb +128 -0
  27. data/app/jobs/bulkrax/delete_work_job.rb +16 -0
  28. data/app/jobs/bulkrax/download_cloud_file_job.rb +18 -0
  29. data/app/jobs/bulkrax/export_work_job.rb +37 -0
  30. data/app/jobs/bulkrax/exporter_job.rb +14 -0
  31. data/app/jobs/bulkrax/import_work_collection_job.rb +41 -0
  32. data/app/jobs/bulkrax/import_work_job.rb +32 -0
  33. data/app/jobs/bulkrax/importer_job.rb +26 -0
  34. data/app/mailers/bulkrax/application_mailer.rb +8 -0
  35. data/app/matchers/bulkrax/application_matcher.rb +113 -0
  36. data/app/matchers/bulkrax/bagit_matcher.rb +6 -0
  37. data/app/matchers/bulkrax/csv_matcher.rb +6 -0
  38. data/app/matchers/bulkrax/oai_matcher.rb +6 -0
  39. data/app/models/bulkrax/application_record.rb +7 -0
  40. data/app/models/bulkrax/csv_collection_entry.rb +19 -0
  41. data/app/models/bulkrax/csv_entry.rb +163 -0
  42. data/app/models/bulkrax/entry.rb +104 -0
  43. data/app/models/bulkrax/exporter.rb +122 -0
  44. data/app/models/bulkrax/exporter_run.rb +7 -0
  45. data/app/models/bulkrax/import_failed.rb +13 -0
  46. data/app/models/bulkrax/importer.rb +155 -0
  47. data/app/models/bulkrax/importer_run.rb +8 -0
  48. data/app/models/bulkrax/oai_dc_entry.rb +6 -0
  49. data/app/models/bulkrax/oai_entry.rb +74 -0
  50. data/app/models/bulkrax/oai_qualified_dc_entry.rb +6 -0
  51. data/app/models/bulkrax/oai_set_entry.rb +19 -0
  52. data/app/models/bulkrax/rdf_collection_entry.rb +19 -0
  53. data/app/models/bulkrax/rdf_entry.rb +90 -0
  54. data/app/models/bulkrax/status.rb +25 -0
  55. data/app/models/bulkrax/xml_entry.rb +73 -0
  56. data/app/models/concerns/bulkrax/download_behavior.rb +61 -0
  57. data/app/models/concerns/bulkrax/errored_entries.rb +45 -0
  58. data/app/models/concerns/bulkrax/export_behavior.rb +58 -0
  59. data/app/models/concerns/bulkrax/file_factory.rb +140 -0
  60. data/app/models/concerns/bulkrax/has_local_processing.rb +7 -0
  61. data/app/models/concerns/bulkrax/has_matchers.rb +155 -0
  62. data/app/models/concerns/bulkrax/import_behavior.rb +90 -0
  63. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +34 -0
  64. data/app/models/concerns/bulkrax/status_info.rb +56 -0
  65. data/app/parsers/bulkrax/application_parser.rb +299 -0
  66. data/app/parsers/bulkrax/bagit_parser.rb +157 -0
  67. data/app/parsers/bulkrax/csv_parser.rb +266 -0
  68. data/app/parsers/bulkrax/oai_dc_parser.rb +130 -0
  69. data/app/parsers/bulkrax/oai_qualified_dc_parser.rb +9 -0
  70. data/app/parsers/bulkrax/xml_parser.rb +103 -0
  71. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +19 -0
  72. data/app/views/bulkrax/entries/_raw_metadata.html.erb +19 -0
  73. data/app/views/bulkrax/entries/show.html.erb +63 -0
  74. data/app/views/bulkrax/exporters/_form.html.erb +120 -0
  75. data/app/views/bulkrax/exporters/edit.html.erb +23 -0
  76. data/app/views/bulkrax/exporters/index.html.erb +67 -0
  77. data/app/views/bulkrax/exporters/new.html.erb +23 -0
  78. data/app/views/bulkrax/exporters/show.html.erb +124 -0
  79. data/app/views/bulkrax/importers/_bagit_fields.html.erb +54 -0
  80. data/app/views/bulkrax/importers/_browse_everything.html.erb +12 -0
  81. data/app/views/bulkrax/importers/_csv_fields.html.erb +39 -0
  82. data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +16 -0
  83. data/app/views/bulkrax/importers/_form.html.erb +35 -0
  84. data/app/views/bulkrax/importers/_oai_fields.html.erb +42 -0
  85. data/app/views/bulkrax/importers/_xml_fields.html.erb +60 -0
  86. data/app/views/bulkrax/importers/edit.html.erb +20 -0
  87. data/app/views/bulkrax/importers/index.html.erb +77 -0
  88. data/app/views/bulkrax/importers/new.html.erb +25 -0
  89. data/app/views/bulkrax/importers/show.html.erb +175 -0
  90. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +37 -0
  91. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +52 -0
  92. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +39 -0
  93. data/app/views/hyrax/dashboard/sidebar/_bulkrax_sidebar_additions.html.erb +6 -0
  94. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +19 -0
  95. data/app/views/layouts/bulkrax/application.html.erb +14 -0
  96. data/config/locales/bulkrax.en.yml +36 -0
  97. data/config/routes.rb +18 -0
  98. data/db/migrate/20181011230201_create_bulkrax_importers.rb +18 -0
  99. data/db/migrate/20181011230228_create_bulkrax_importer_runs.rb +16 -0
  100. data/db/migrate/20190325183136_create_bulkrax_entries.rb +16 -0
  101. data/db/migrate/20190601221109_add_status_to_entry.rb +9 -0
  102. data/db/migrate/20190715161939_add_collections_to_importer_runs.rb +6 -0
  103. data/db/migrate/20190715162044_change_collection_ids_on_entries.rb +5 -0
  104. data/db/migrate/20190729124607_create_bulkrax_exporters.rb +19 -0
  105. data/db/migrate/20190729134158_create_bulkrax_exporter_runs.rb +14 -0
  106. data/db/migrate/20190731114016_change_importer_and_exporter_to_polymorphic.rb +12 -0
  107. data/db/migrate/20191203225129_add_total_collection_records_to_importer_runs.rb +5 -0
  108. data/db/migrate/20191204191623_add_children_to_importer_runs.rb +6 -0
  109. data/db/migrate/20191204223857_change_total_records_to_total_work_entries.rb +6 -0
  110. data/db/migrate/20191212155530_change_entry_last_error.rb +19 -0
  111. data/db/migrate/20200108194557_add_validate_only_to_bulkrax_importers.rb +5 -0
  112. data/db/migrate/20200301232856_add_status_to_importers.rb +9 -0
  113. data/db/migrate/20200312190638_remove_foreign_key_from_bulkrax_entries.rb +5 -0
  114. data/db/migrate/20200326235838_add_status_to_exporters.rb +7 -0
  115. data/db/migrate/20200601204556_add_invalid_record_to_importer_run.rb +5 -0
  116. data/db/migrate/20200818055819_create_bulkrax_statuses.rb +18 -0
  117. data/db/migrate/20200819054016_move_to_statuses.rb +30 -0
  118. data/db/migrate/20201106014204_add_date_filter_and_status_to_bulkrax_exporters.rb +7 -0
  119. data/db/migrate/20201117220007_add_workflow_status_to_bulkrax_exporter.rb +5 -0
  120. data/db/migrate/20210806044408_remove_unused_last_error.rb +7 -0
  121. data/db/migrate/20210806065737_increase_text_sizes.rb +12 -0
  122. data/lib/bulkrax.rb +161 -0
  123. data/lib/bulkrax/engine.rb +37 -0
  124. data/lib/bulkrax/version.rb +5 -0
  125. data/lib/generators/bulkrax/install_generator.rb +80 -0
  126. data/lib/generators/bulkrax/templates/README +3 -0
  127. data/lib/generators/bulkrax/templates/app/assets/images/bulkrax/removed.png +0 -0
  128. data/lib/generators/bulkrax/templates/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  129. data/lib/generators/bulkrax/templates/bin/importer +140 -0
  130. data/lib/generators/bulkrax/templates/config/bulkrax_api.yml +84 -0
  131. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +72 -0
  132. data/lib/tasks/bulkrax_tasks.rake +6 -0
  133. metadata +388 -0
@@ -0,0 +1,124 @@
1
+ <p id='notice'><%= notice %></p>
2
+
3
+ <div class='col-xs-12 main-header'>
4
+ <h1><span class='fa fa-cloud-download' aria-hidden='true'></span> Exporter: <%= @exporter.name %></h1>
5
+ </div>
6
+
7
+ <div class='panel panel-default'>
8
+ <div class='panel-body'>
9
+
10
+ <p class='bulkrax-p-align'>
11
+ <strong><%= t('bulkrax.exporter.labels.name') %>:</strong>
12
+ <%= @exporter.name %>
13
+ </p>
14
+
15
+ <p class='bulkrax-p-align'>
16
+ <strong><%= t('bulkrax.exporter.labels.user') %>:</strong>
17
+ <%= @exporter.user %>
18
+ </p>
19
+
20
+ <p class='bulkrax-p-align'>
21
+ <strong><%= t('bulkrax.exporter.labels.export_type') %>:</strong>
22
+ <%= @exporter.export_type %>
23
+ </p>
24
+
25
+ <p class='bulkrax-p-align'>
26
+ <strong><%= t('bulkrax.exporter.labels.export_from') %>:</strong>
27
+ <%= @exporter.export_from %>
28
+ </p>
29
+
30
+ <p class='bulkrax-p-align'>
31
+ <strong><%= t('bulkrax.exporter.labels.export_source') %>:</strong>
32
+ <% case @exporter.export_from %>
33
+ <% when 'collection' %>
34
+ <% collection = Collection.find(@exporter.export_source) %>
35
+ <%= link_to collection&.title&.first, hyrax.dashboard_collection_path(collection.id) %>
36
+ <% when 'importer' %>
37
+ <% importer = Bulkrax::Importer.find(@exporter.export_source) %>
38
+ <%= link_to importer.name, bulkrax.importer_path(importer.id) %>
39
+ <% when 'worktype' %>
40
+ <%= @exporter.export_source %>
41
+ <% end %>
42
+ </p>
43
+
44
+ <p class='bulkrax-p-align'>
45
+ <strong><%= t('bulkrax.exporter.labels.parser_klass') %>:</strong>
46
+ <%= @exporter.parser_klass %>
47
+ </p>
48
+
49
+ <p class='bulkrax-p-align'>
50
+ <strong><%= t('bulkrax.exporter.labels.limit') %>:</strong>
51
+ <%= @exporter.limit %>
52
+ </p>
53
+
54
+ <%= render partial: 'bulkrax/shared/bulkrax_field_mapping', locals: {item: @exporter} %>
55
+
56
+ <%# Currently, no parser-specific fields exist on Exporter,
57
+ thus there's no real reason to always show this field %>
58
+ <% if @exporter.parser_fields.present? %>
59
+ <p class='bulkrax-p-align'>
60
+ <strong><%= t('bulkrax.exporter.labels.parser_fields') %>:</strong><br>
61
+ <% @exporter.parser_fields.each do |k, v| %>
62
+ <%= k %>: <%= v %><br>
63
+ <% end %>
64
+ </p>
65
+ <% end %>
66
+
67
+ <p class='bulkrax-p-align'><strong><%= t('bulkrax.exporter.labels.field_mapping') %>:</strong></p>
68
+
69
+ <p class='bulkrax-p-align'>
70
+ <strong><%= t('bulkrax.exporter.labels.total_work_entries') %>:</strong>
71
+ <%= @exporter.exporter_runs.last&.total_work_entries %>
72
+ </p>
73
+ <br>
74
+ <div class="bulkrax-nav-tab-table-left-align">
75
+ <h2>Entries</h2>
76
+ <table class='table table-striped'>
77
+ <thead>
78
+ <tr>
79
+ <th>Identifier</th>
80
+ <th>Collection</th>
81
+ <th>Entry ID</th>
82
+ <th>Status</th>
83
+ <th>Errors</th>
84
+ <th>Status Set At</th>
85
+ <th>Actions</th>
86
+ </tr>
87
+ </thead>
88
+ <tbody>
89
+ <% @work_entries.each do |e| %>
90
+ <tr>
91
+ <td><%= link_to e.identifier, bulkrax.exporter_entry_path(@exporter.id, e.id) %></td>
92
+ <% if e.parsed_metadata.present? && e.parsed_metadata.dig('collections').present? %>
93
+ <td><%= e.parsed_metadata.dig('collections').map {|c| c['id'] }.join('; ') %></td>
94
+ <% elsif e.raw_metadata.present? %>
95
+ <td><%= Array.wrap(e.raw_metadata.dig('collection')).join(';') %></td>
96
+ <% else %>
97
+ <td></td>
98
+ <% end %>
99
+ <td><%= e.id %></td>
100
+ <% if e.status == 'Complete' %>
101
+ <td><span class='glyphicon glyphicon-ok' style='color: green;'></span> <%= e.status %></td>
102
+ <% else %>
103
+ <td><span class='glyphicon glyphicon-remove' style='color: red;'></span> <%= e.status %></td>
104
+ <% end %>
105
+ <% if e.last_error.present? %>
106
+ <td><%= link_to e.last_error.dig('error_class'), bulkrax.exporter_entry_path(@exporter.id, e.id) %></td>
107
+ <% else %>
108
+ <td></td>
109
+ <% end %>
110
+ <td><%= e.status_at %></td>
111
+ <td><%= link_to raw("<span class='glyphicon glyphicon-info-sign'></span>"), bulkrax.exporter_entry_path(@exporter.id, e.id) %></td>
112
+ </tr>
113
+ <% end %>
114
+ </tbody>
115
+ </table>
116
+ <%= page_entries_info(@work_entries) %><br>
117
+ <%= paginate(@work_entries, param_name: :work_entries_page) %>
118
+ <br>
119
+ <%= link_to 'Edit', edit_exporter_path(@exporter) %>
120
+ |
121
+ <%= link_to 'Back', exporters_path %>
122
+ </div>
123
+ </div>
124
+ </div>
@@ -0,0 +1,54 @@
1
+ <div class='bagit_fields'>
2
+
3
+ <%#= fi.input :metadata_type,
4
+ collection: importer.import_metadata_type,
5
+ selected: importer.parser_fields['metadata_type'],
6
+ include_blank: true,
7
+ input_html: { class: 'form-control' }
8
+ %>
9
+ <%= fi.input :metadata_file_name, as: :string, input_html: { value: importer.parser_fields['metadata_file_name'] } %>
10
+
11
+ <%= fi.input :metadata_format,
12
+ collection: importer.import_metadata_format,
13
+ selected: importer.parser_fields['metadata_format'],
14
+ include_blank: true,
15
+ input_html: { class: 'form-control' }
16
+ %>
17
+
18
+ <%= fi.input :visibility,
19
+ collection: [
20
+ ['Public', 'open'],
21
+ ['Private', 'restricted']
22
+ ],
23
+ selected: importer.parser_fields['visibility'] || 'open',
24
+ input_html: { class: 'form-control' }
25
+ %>
26
+
27
+ <% rights_statements = Hyrax.config.rights_statement_service_class.new %>
28
+ <%= fi.input :rights_statement,
29
+ collection: rights_statements.select_active_options,
30
+ selected: importer.parser_fields['rights_statement'],
31
+ include_blank: true,
32
+ item_helper: rights_statements.method(:include_current_value),
33
+ input_html: { class: 'form-control' } ,
34
+ required: false
35
+ %>
36
+ <%= fi.input :override_rights_statement, as: :boolean, hint: 'If checked, always use the selected rights statment. If unchecked, use rights or rights_statement from the record and only use the provided value if dc:rights is blank.', input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
37
+
38
+ <h4>Bag or Bags to Import:</h4>
39
+ <p>File upload and Cloud File upload must be a Zip file containing a single BagIt Bag, or a folder containing multiple BagIt Bags.</p>
40
+ <p>The Server Path can point to a BagIt Bag, a folder containing BagIt Bags, or a zip file containing either.</p>
41
+
42
+ <%= fi.input :file_style, collection: ['Upload a File', 'Specify a Path on the Server', 'Add Cloud File'], as: :radio_buttons, label: false %>
43
+ <div id='file_upload'>
44
+ <%= fi.input 'file', as: :file, input_html: {accept: 'application/zip'} %><br />
45
+ </div>
46
+ <div id='file_path'>
47
+ <%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
48
+ </div>
49
+ <div id='cloud'>
50
+ <% if Hyrax.config.browse_everything? %>
51
+ <%= render 'browse_everything', form: form %>
52
+ <% end %>
53
+ </div>
54
+ </div>
@@ -0,0 +1,12 @@
1
+
2
+ <%
3
+ f = "#{form.lookup_action}_importer"
4
+ f = "#{f}_#{@importer.id}" unless @importer.new_record?
5
+ %>
6
+ <div id='cloud-files'>
7
+ <button type="button" data-toggle="browse-everything" data-route="<%=browse_everything_engine.root_path%>"
8
+ data-target="#<%= f %>" class="btn btn-primary" id="browse">
9
+ <span class="glyphicon glyphicon-plus"></span>
10
+ Add Cloud Files
11
+ </button>
12
+ </div>
@@ -0,0 +1,39 @@
1
+ <div class='csv_fields'>
2
+
3
+ <%= fi.input :visibility,
4
+ collection: [
5
+ ['Public', 'open'],
6
+ ['Private', 'restricted']
7
+ ],
8
+ selected: importer.parser_fields['visibility'] || 'open',
9
+ input_html: { class: 'form-control' }
10
+ %>
11
+
12
+ <% rights_statements = Hyrax.config.rights_statement_service_class.new %>
13
+ <%= fi.input :rights_statement,
14
+ collection: rights_statements.select_active_options,
15
+ selected: importer.parser_fields['rights_statement'],
16
+ include_blank: true,
17
+ item_helper: rights_statements.method(:include_current_value),
18
+ input_html: { class: 'form-control' },
19
+ required: false
20
+ %>
21
+ <%= fi.input :override_rights_statement, as: :boolean, hint: 'If checked, always use the selected rights statment. If unchecked, use rights or rights_statement from the record and only use the provided value if dc:rights is blank.', input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
22
+
23
+ <h4>Add CSV File to Import:</h4>
24
+ <%# accept a single file upload; data files and bags will need to be added another way %>
25
+
26
+ <%= fi.input :file_style, collection: ['Upload a File', 'Specify a Path on the Server'], as: :radio_buttons, label: false %>
27
+ <div id='file_upload'>
28
+ <%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip' } %><br />
29
+ </div>
30
+ <div id='file_path'>
31
+ <%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
32
+ </div>
33
+ <% if Hyrax.config.browse_everything? %>
34
+ <h4>Add Files to Import:</h4>
35
+ <p>Choose files to upload. The filenames must be unique, and the filenames must be referenced in a column called 'file' in the accompanying CSV file.</p>
36
+ <%= render 'browse_everything', form: form %>
37
+ <% end %>
38
+ <br />
39
+ </div>
@@ -0,0 +1,16 @@
1
+
2
+ <%# If we can know the parser, we can vary the buttons here %>
3
+
4
+ <% if @importer.importer_runs.blank? %>
5
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
6
+ | <%= form.button :submit, value: 'Update and Import (importer has not yet been run)', class: 'btn btn-primary' %>
7
+ <% elsif @importer.parser_klass.include?('Oai') %>
8
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
9
+ | <%= form.button :submit, value: 'Update and Harvest Updated Items', class: 'btn btn-primary' %>
10
+ | <%= form.button :submit, value: 'Update and Re-Harvest All Items', class: 'btn btn-primary' %>
11
+ <% else %>
12
+ <%= form.button :submit, value: 'Update Importer', class: 'btn btn-primary' %>
13
+ | <%= form.button :submit, value: 'Update and Re-Import (update metadata only)', class: 'btn btn-primary' %>
14
+ | <%= form.button :submit, value: 'Update All (update metadata and update files)', class: 'btn btn-primary' %>
15
+ | <%= form.button :submit, value: 'Update and Re-Import (update metadata and replace files)', class: 'btn btn-primary', data: {confirm: "Are you sure? This will remove all files before adding them from the import."} %>
16
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <div class="panel-body">
2
+ <% if importer.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(importer.errors.count, "error") %> prohibited this importer from being saved:</h2>
5
+
6
+ <ul>
7
+ <% importer.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <%= form.input :name %>
15
+
16
+ <%= form.input :admin_set_id, collection: available_admin_sets %>
17
+
18
+ <%= form.hidden_field :user_id, value: current_user.id %>
19
+
20
+ <%= form.input :frequency, collection: form.object.class.frequency_enums %>
21
+
22
+ <%= form.input :limit, as: :integer, hint: 'leave blank or 0 for all records' %>
23
+
24
+ <%= form.input :parser_klass, collection: Bulkrax.parsers.map {|p| [p[:name], p[:class_name], {'data-partial' => p[:partial]}]}, label: "Parser" %>
25
+
26
+ <%= form.fields_for :parser_fields do |fi| %>
27
+ <div class='parser_fields'>
28
+ <p>Specific fields for each parser are available only when a parser is selected</p>
29
+ <% Bulkrax.parsers.map {|p| p[:partial]}.uniq.each do |partial| %>
30
+ <%= render partial: partial, locals: {form: form, fi: fi, importer: importer} %>
31
+ <% end %>
32
+ </div>
33
+ <% end %>
34
+
35
+ </div>
@@ -0,0 +1,42 @@
1
+ <div class='oai_fields'>
2
+ <%= fi.input :base_url, as: :string, input_html: { value: importer.parser_fields['base_url'] } %>
3
+
4
+ <%= fi.input :metadata_prefix, as: :string, hint: 'Such as oai_dc, dcterms or oai_qdc', input_html: { value: importer.parser_fields['metadata_prefix'] } %>
5
+
6
+ <%= fi.input :set, collection: [importer.parser_fields['set']], label: 'Set (source)', selected: importer.parser_fields['set'] %>
7
+ <button type="button" class="btn btn-default refresh-set-source">Refresh Sets</button>
8
+
9
+ <%= fi.input :visibility,
10
+ collection: [
11
+ ['Public', 'open'],
12
+ ['Private', 'restricted']
13
+ ],
14
+ selected: importer.parser_fields['visibility'] || 'open',
15
+ input_html: { class: 'form-control' }
16
+ %>
17
+
18
+ <% rights_statements = Hyrax.config.rights_statement_service_class.new %>
19
+ <%= fi.input :rights_statement,
20
+ collection: rights_statements.select_active_options,
21
+ selected: importer.parser_fields['rights_statement'],
22
+ include_blank: true,
23
+ item_helper: rights_statements.method(:include_current_value),
24
+ input_html: { class: 'form-control' },
25
+ required: false
26
+ %>
27
+ <%= fi.input :override_rights_statement, as: :boolean, hint: 'If checked, always use the selected rights statment. If unchecked, use dc:rights from the record and only use the provided value if dc:rights is blank.', input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
28
+ <%= fi.input :thumbnail_url, required: false, as: :string, input_html: { value: importer.parser_fields['thumbnail_url'] } %>
29
+ <div class="help-block well well-sm">
30
+ <p>
31
+ The Thumbnail URL allows for basic templating and substitution on any identified information in to the url. For example:
32
+ </p>
33
+
34
+ <p>
35
+ http://commons.ptsem.edu/?cover=<&#37= identifier.split(':').last &#37>&size=L
36
+ </p>
37
+
38
+ <p>
39
+ http://commons.ptsem.edu/?cover=<&#37= record.header.identifier.split(':').last &#37>&size=L
40
+ </p>
41
+ </div>
42
+ </div>
@@ -0,0 +1,60 @@
1
+ <div class='xml_fields'>
2
+
3
+ <%# @todo improve on this implementation.
4
+ As it stands, it's a hostage to namespaces,
5
+ eg. dc:title
6
+ if namespaces aren't in the xml, we would have to specify dc:title
7
+ but if the namespaces ARE present, we remove them so we would need title
8
+ %>
9
+ <%= fi.input :record_element,
10
+ hint: 'Provide the xml element name to use to identify the record, or records, eg. ROW - each record in the attached XML is wrapped in a <ROW> tag.',
11
+ input_html: { value: importer.parser_fields['record_element'] }
12
+ %>
13
+
14
+ <%= fi.input :import_type,
15
+ collection: [
16
+ ['Single Work per Metadata File', 'single'],
17
+ ['Multiple Works per Metadata File', 'multiple']
18
+ ],
19
+ selected: importer.parser_fields['import_type'],
20
+ input_html: { class: 'form-control' }
21
+ %>
22
+
23
+ <h4>Visiblity</h4>
24
+
25
+ <%= fi.input :visibility,
26
+ collection: [
27
+ ['Public', 'open'],
28
+ ['Private', 'restricted']
29
+ ],
30
+ selected: importer.parser_fields['visibility'] || 'open',
31
+ input_html: { class: 'form-control' }
32
+ %>
33
+
34
+ <% rights_statements = Hyrax.config.rights_statement_service_class.new %>
35
+ <%= fi.input :rights_statement,
36
+ collection: rights_statements.select_active_options,
37
+ selected: importer.parser_fields['rights_statement'],
38
+ include_blank: true,
39
+ item_helper: rights_statements.method(:include_current_value),
40
+ input_html: { class: 'form-control' },
41
+ required: false %>
42
+ <%= fi.input :override_rights_statement, as: :boolean, hint: 'If checked, always use the selected rights statment. If unchecked, use rights or rights_statement from the record and only use the provided value if dc:rights is blank.', input_html: { checked: (importer.parser_fields['override_rights_statement'] == "1") } %>
43
+
44
+ <h4>XML and files to Import:</h4>
45
+ <p>File upload and Cloud File upload MUST be a either a single XML file (for metadata only import) OR a Zip file containing the XML files and data files, each in a separate folder.</p>
46
+ <p>The Server Path can point to a folder containing XML files and data files to import, or direct to the XML file itself.</p>
47
+
48
+ <%= fi.input :file_style, collection: ['Upload a File', 'Specify a Path on the Server', 'Add Cloud File'], as: :radio_buttons, label: false %>
49
+ <div id='file_upload'>
50
+ <%= fi.input 'file', as: :file, input_html: {accept: ['application/zip', 'application/xml']} %><br />
51
+ </div>
52
+ <div id='file_path'>
53
+ <%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
54
+ </div>
55
+ <div id='cloud'>
56
+ <% if Hyrax.config.browse_everything? %>
57
+ <%= render 'browse_everything', form: form %>
58
+ <% end %>
59
+ </div>
60
+ </div>
@@ -0,0 +1,20 @@
1
+ <% provide :page_header do %>
2
+ <h1><span class="fa fa-edit" aria-hidden="true"></span> Edit Importer</h1>
3
+ <% end %>
4
+
5
+ <div class="row">
6
+ <div class="col-md-12">
7
+ <div class="panel panel-default tabs">
8
+ <%= simple_form_for @importer, html: { multipart: true } do |form| %>
9
+ <%= render 'form', importer: @importer, form: form %>
10
+ <div class="panel-footer">
11
+ <div class='pull-right'>
12
+ <%= render 'edit_form_buttons', form: form %>
13
+ <% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
14
+ | <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
15
+ </div>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ </div>
20
+ </div>
@@ -0,0 +1,77 @@
1
+ <% provide :page_header do %>
2
+ <h1><span class="fa fa-cloud-upload" aria-hidden="true"></span> Importers</h1>
3
+ <div class="pull-right">
4
+ <%= link_to new_importer_path, class: 'btn btn-primary' do %>
5
+ <span class="fa fa-edit" aria-hidden="true"></span> <%= t(:'helpers.action.importer.new') %>
6
+ <% end %>
7
+ </div>
8
+ <% end %>
9
+
10
+ <div class="panel panel-default">
11
+ <div class="panel-body">
12
+ <% if @importers.present? %>
13
+ <div class="table-responsive">
14
+ <table class="table table-striped datatable">
15
+ <thead>
16
+ <tr>
17
+ <th scope="col">Name</th>
18
+ <th scope="col">Status</th>
19
+ <th scope="col">Last Run</th>
20
+ <th scope="col">Next Run</th>
21
+ <th scope="col">Entries Enqueued</th>
22
+ <th scope="col">Entries Processed</th>
23
+ <th scope="col">Entries Failed</th>
24
+ <th scope="col">Entries Deleted Upstream</th>
25
+ <th scope="col">Total Collection Entries</th>
26
+ <th scope="col">Total Work Entries</th>
27
+ <th scope="col"></th>
28
+ <th scope="col"></th>
29
+ <th scope="col"></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <% @importers.each do |importer| %>
34
+ <tr>
35
+ <th scope="row"><%= link_to importer.name, importer_path(importer) %></th>
36
+ <td>
37
+ <%= importer.status %>
38
+ </td>
39
+ <td><%= importer.last_imported_at.strftime("%b %d, %Y") if importer.last_imported_at %></td>
40
+ <td><%= importer.next_import_at.strftime("%b %d, %Y") if importer.next_import_at %></td>
41
+ <td><%= importer.importer_runs.last&.enqueued_records %></td>
42
+ <td><%= (importer.importer_runs.last&.processed_collections || 0) + (importer.importer_runs.last&.processed_records || 0) %></td>
43
+ <td><%= (importer.importer_runs.last&.failed_collections || 0) + (importer.importer_runs.last&.failed_records || 0) %></td>
44
+ <td><%= importer.importer_runs.last&.deleted_records %></td>
45
+ <td><%= importer.importer_runs.last&.total_collection_entries %></td>
46
+ <td><%= importer.importer_runs.last&.total_work_entries %></td>
47
+ <td><%= link_to raw('<span class="glyphicon glyphicon-info-sign"></span>'), importer_path(importer) %></td>
48
+ <td><%= link_to raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_importer_path(importer) %></td>
49
+ <td><%= link_to raw('<span class="glyphicon glyphicon-remove"></span>'), importer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
50
+ </tr>
51
+ <% end %>
52
+ </tbody>
53
+ </table>
54
+ </div>
55
+ <% else %>
56
+ <p>No importers have been created.</p>
57
+ <% end %>
58
+ </div>
59
+ </div>
60
+
61
+ <script>
62
+ $(function() {
63
+ $('#DataTables_Table_0').DataTable({
64
+ destroy: true, /* Reinitialize DataTable with config below */
65
+ 'columnDefs': [
66
+ { 'orderable': true, 'targets': [...Array(10).keys()] },
67
+ { 'orderable': false, 'targets': [10, 11, 12] }
68
+ ],
69
+ 'language': {
70
+ 'info': 'Showing _START_ to _END_ of _TOTAL_ importers',
71
+ 'infoEmpty': 'No importers to show',
72
+ 'infoFiltered': '(filtered from _MAX_ total importers)',
73
+ 'lengthMenu': 'Show _MENU_ importers'
74
+ }
75
+ })
76
+ })
77
+ </script>