bulk_ops 0.1.3
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 +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,466 @@
|
|
1
|
+
class BulkOps::WorkProxy < ActiveRecord::Base
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
OPTION_FIELDS = ['visibility','work type']
|
5
|
+
RELATIONSHIP_FIELDS = ['parent','child','collection','next','order']
|
6
|
+
REFERENCE_IDENTIFIER_FIELDS = ['Reference Identifier','ref_id','Reference ID','Relationship ID','Relationship Identifier','Reference Identifier Type','Reference ID Type','Ref ID Type','relationship_identifier_type','relationship_id_type']
|
7
|
+
FILE_FIELDS = ['file','files','filename','filenames']
|
8
|
+
FILE_ACTIONS = ['add','upload','remove','delete']
|
9
|
+
SEPARATOR = ';'
|
10
|
+
self.table_name = "bulk_ops_work_proxies"
|
11
|
+
belongs_to :operation, class_name: "BulkOps::Operation", foreign_key: "operation_id"
|
12
|
+
has_many :relationships, class_name: "BulkOps::Relationship"
|
13
|
+
|
14
|
+
attr_accessor :proxy_errors
|
15
|
+
|
16
|
+
def initialize *args
|
17
|
+
super *args
|
18
|
+
place_hold if @work_id
|
19
|
+
end
|
20
|
+
|
21
|
+
def work
|
22
|
+
return @work if @work
|
23
|
+
begin
|
24
|
+
@work = ActiveFedora::Base.find(work_id)
|
25
|
+
rescue
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
return @work
|
29
|
+
end
|
30
|
+
|
31
|
+
def work_type
|
32
|
+
super || operation.work_type || "Work"
|
33
|
+
end
|
34
|
+
|
35
|
+
def place_hold
|
36
|
+
# TODO make it so nobody can edit the work
|
37
|
+
end
|
38
|
+
|
39
|
+
def lift_hold
|
40
|
+
# TODO make it so people can edit the work again
|
41
|
+
end
|
42
|
+
|
43
|
+
def interpret_data raw_data
|
44
|
+
admin_set = AdminSet.where(title: "Bulk Ingest Set").first || AdminSet.find(AdminSet.find_or_create_default_admin_set_id)
|
45
|
+
metadata = {admin_set_id: admin_set.id}
|
46
|
+
metadata.merge! interpret_file_fields(raw_data)
|
47
|
+
metadata.merge! interpret_controlled_fields(raw_data)
|
48
|
+
metadata.merge! interpret_scalar_fields(raw_data)
|
49
|
+
metadata.merge! interpret_relationship_fields(raw_data )
|
50
|
+
metadata.merge! interpret_option_fields(raw_data)
|
51
|
+
metadata = setAdminSet(metadata)
|
52
|
+
return metadata
|
53
|
+
end
|
54
|
+
|
55
|
+
def proxy_errors
|
56
|
+
@proxy_errors ||= []
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def is_file_field? field
|
62
|
+
operation.is_file_field? field
|
63
|
+
end
|
64
|
+
|
65
|
+
def record_exists? id
|
66
|
+
operation.record_exists? id
|
67
|
+
end
|
68
|
+
|
69
|
+
def localAuthUrl(property, value)
|
70
|
+
return value if (auth = getLocalAuth(property)).nil?
|
71
|
+
url = findAuthUrl(auth, value) || mintLocalAuthUrl(auth,value)
|
72
|
+
return url
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_collection(collection)
|
76
|
+
cols = Collection.where(id: collection)
|
77
|
+
cols += Collection.where(title: collection).select{|col| col.title.first == collection}
|
78
|
+
return cols.last unless cols.empty?
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_or_create_collection(collection)
|
83
|
+
col = find_collection(collection)
|
84
|
+
return col if col
|
85
|
+
return false if collection.to_i > 0
|
86
|
+
col = Collection.create(title: [collection.to_s], depositor: operation.user.email, collection_type: Hyrax::CollectionType.all.first)
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_remote_id(value, authority: nil, property: nil)
|
90
|
+
return false
|
91
|
+
#TODO retrieve URL for this value from the specified remote authr
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_param_name(name)
|
95
|
+
name.titleize.gsub(/\s+/, "").camelcase(:lower)
|
96
|
+
end
|
97
|
+
|
98
|
+
def schema
|
99
|
+
ScoobySnacks::METADATA_SCHEMA
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_field_name(field)
|
103
|
+
operation.find_field_name(field)
|
104
|
+
end
|
105
|
+
|
106
|
+
def downcase_first_letter(str)
|
107
|
+
return "" unless str
|
108
|
+
str[0].downcase + str[1..-1]
|
109
|
+
end
|
110
|
+
|
111
|
+
def split_values value_string
|
112
|
+
# Split values on all un-escaped separator character (escape character is '\')
|
113
|
+
# Then replace all escaped separator charactors with un-escaped versions
|
114
|
+
value_string.split(/(?<!\\)#{SEPARATOR}/).map{|val| val.gsub("\\#{SEPARATOR}",SEPARATOR)}
|
115
|
+
end
|
116
|
+
|
117
|
+
def interpret_controlled_fields raw_data
|
118
|
+
|
119
|
+
# The labels array tracks the contents of columns marked as labels,
|
120
|
+
# which may require special validation
|
121
|
+
labels = {}
|
122
|
+
|
123
|
+
# This hash is populated with relevant data as we loop through the fields
|
124
|
+
controlled_data = {}
|
125
|
+
|
126
|
+
raw_data.each do |field_name, value|
|
127
|
+
next if value.blank? or field_name.blank?
|
128
|
+
field_name = field_name.to_s
|
129
|
+
|
130
|
+
#If our CSV interpreter is feeding us the headers as a line, ignore it.
|
131
|
+
next if field_name == value
|
132
|
+
|
133
|
+
#check if they are using the 'field_name.authority' syntax
|
134
|
+
authority = nil
|
135
|
+
if ((split=field_name.split('.')).count == 2)
|
136
|
+
authority = split.last
|
137
|
+
field_name = split.first
|
138
|
+
end
|
139
|
+
|
140
|
+
# get the field name, if this column is a metadata field
|
141
|
+
field_name_norm = find_field_name(field_name)
|
142
|
+
field = schema.get_field(field_name_norm)
|
143
|
+
|
144
|
+
# Ignore anything that isn't a controlled field
|
145
|
+
next unless field.present? && field.controlled?
|
146
|
+
|
147
|
+
# Keep track of label fields
|
148
|
+
if field_name.downcase.ends_with?("label")
|
149
|
+
next if operation.options["ignore_labels"]
|
150
|
+
labels[field_name_norm] ||= []
|
151
|
+
labels[field_name_norm] += split_values value
|
152
|
+
next unless operation.options["import_labels"]
|
153
|
+
end
|
154
|
+
|
155
|
+
remove = field_name.downcase.starts_with?("remove") || field_name.downcase.starts_with?("delete")
|
156
|
+
|
157
|
+
# handle multiple values
|
158
|
+
split_values(value).each do |value|
|
159
|
+
|
160
|
+
# Decide of we're dealing with a label or url
|
161
|
+
# It's an ID if it's a URL and the name doesn't end in 'label'
|
162
|
+
if value =~ /^#{URI::regexp}$/ and !field_name.downcase.ends_with?("label")
|
163
|
+
id = value
|
164
|
+
label = WorkIndexer.fetch_remote_label(value)
|
165
|
+
error_message = "cannot fetch remote label for url: #{value}"
|
166
|
+
report_error( :cannot_retrieve_label , error_message, url: value, row_number: row_number) unless label
|
167
|
+
else
|
168
|
+
# It's a label, so get the id
|
169
|
+
id = get_remote_id(value, property: field_name_norm, authority: authority) || localAuthUrl(field_name_norm, value)
|
170
|
+
label = value
|
171
|
+
report_error(:cannot_retrieve_url,
|
172
|
+
message: "cannot find or create url for controlled vocabulary label: #{value}",
|
173
|
+
url: value,
|
174
|
+
row_number: row_number) unless id
|
175
|
+
end
|
176
|
+
(controlled_data[field_name_norm] ||= []) << {id: id, label: label, remove: field_name.downcase.starts_with?("remove")}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
#delete any duplicates (if someone listed a url and also its label, or the same url twice)
|
181
|
+
controlled_data.each{|field_name, values| controlled_data[field_name] = values.uniq }
|
182
|
+
|
183
|
+
if operation.options["compare_labels"]
|
184
|
+
controlled_data.each do |field_name,values|
|
185
|
+
unless labels['field'].count == values.count
|
186
|
+
report_error(:mismatched_auth_terms,
|
187
|
+
message: "Different numbers of labels and ids for #{field}",
|
188
|
+
row_number: row_number)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
labels['field'].each do |label|
|
192
|
+
next if controlled_data.any?{|dt| dt["label"] == label}
|
193
|
+
report_error(:mismatched_auth_terms,
|
194
|
+
message: "There are controlled vocab term labels that no provided URL resolves to, in the field #{field}.",
|
195
|
+
row_number: row_number)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Actually add all the data
|
200
|
+
metadata = {}
|
201
|
+
leftover_data = raw_data.dup.to_hash
|
202
|
+
controlled_data.each do |property_name, data|
|
203
|
+
data.each do |datum|
|
204
|
+
atts = {"id" => datum[:id]}
|
205
|
+
atts["_delete"] = true if datum[:remove]
|
206
|
+
metadata["#{property_name}_attributes"] ||= []
|
207
|
+
metadata["#{property_name}_attributes"] << atts
|
208
|
+
leftover_data.except! property_name
|
209
|
+
end
|
210
|
+
end
|
211
|
+
#return [metadata, leftover_data]
|
212
|
+
return metadata
|
213
|
+
end
|
214
|
+
|
215
|
+
def interpret_scalar_fields raw_data
|
216
|
+
metadata = {}
|
217
|
+
raw_data.each do |field, values|
|
218
|
+
next if values.blank? or field.nil? or field == values
|
219
|
+
# get the field name, if this column is a metadata field
|
220
|
+
next unless field_name = find_field_name(field.to_s)
|
221
|
+
field = schema.get_field(field_name)
|
222
|
+
# Ignore controlled fields
|
223
|
+
next if field.controlled?
|
224
|
+
values.split(SEPARATOR).each do |value|
|
225
|
+
next if value.blank?
|
226
|
+
value = value.strip.encode('utf-8', :invalid => :replace, :undef => :replace, :replace => '_') unless value.blank?
|
227
|
+
(metadata[field_name] ||= []) << value
|
228
|
+
end
|
229
|
+
end
|
230
|
+
return metadata
|
231
|
+
end
|
232
|
+
|
233
|
+
def interpret_file_fields raw_data
|
234
|
+
# This method handles file additions and deletions from the spreadsheet
|
235
|
+
# if additional files need to be deleted because the update is set to replace
|
236
|
+
# some or all existing files, those replacement-related deletions are handled
|
237
|
+
# by the BulkOps::Operation.
|
238
|
+
#
|
239
|
+
# TODO: THIS DOES NOT YET MANAGE THE ORDER OF INGESTED FILESETS
|
240
|
+
|
241
|
+
metadata = {}
|
242
|
+
raw_data.each do |field, value|
|
243
|
+
next if value.blank? or field.blank?
|
244
|
+
field = field.to_s
|
245
|
+
#If our CSV interpreter is feeding us the headers as a line, ignore it.
|
246
|
+
next if field == value
|
247
|
+
|
248
|
+
|
249
|
+
# Check if this is a file field, and whether we are removing or adding a file
|
250
|
+
next unless (action = is_file_field?(field))
|
251
|
+
|
252
|
+
# Move on if this field is the name of another property (e.g. masterFilename)
|
253
|
+
next if find_field_name(field)
|
254
|
+
|
255
|
+
# Check if we are removing a file
|
256
|
+
if action == "remove"
|
257
|
+
get_removed_filesets(value).each { |fileset_id| delete_file_set(file_set_id) }
|
258
|
+
else
|
259
|
+
# Add a file
|
260
|
+
operation.get_file_paths(value).each do |filepath|
|
261
|
+
begin
|
262
|
+
uploaded_file = Hyrax::UploadedFile.create(file: File.open(filepath), user: operation.user)
|
263
|
+
(metadata[:uploaded_files] ||= []) << uploaded_file.id unless uploaded_file.id.nil?
|
264
|
+
rescue Exception => e
|
265
|
+
report_error(:upload_error,
|
266
|
+
message: "Error opening file: #{ filepath } -- #{e}",
|
267
|
+
file: File.join(BulkOps::Operation::INGEST_MEDIA_PATH,filename),
|
268
|
+
row_number: row_number)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
return metadata
|
274
|
+
end
|
275
|
+
|
276
|
+
def interpret_option_fields raw_data
|
277
|
+
raw_data.each do |field,value|
|
278
|
+
next if value.blank? or field.blank?
|
279
|
+
field = field.to_s
|
280
|
+
next if value == field
|
281
|
+
|
282
|
+
normfield = field.downcase.parameterize.gsub(/[_\s-]/,'')
|
283
|
+
if ["visibility", "public"].include?(normfield)
|
284
|
+
update(visibility: format_visibility(value))
|
285
|
+
end
|
286
|
+
if ["worktype","model","type"].include?(normfield)
|
287
|
+
update(work_type: format_worktype(value) )
|
288
|
+
end
|
289
|
+
if ["referenceidentifier",
|
290
|
+
"referenceid",
|
291
|
+
"refid",
|
292
|
+
"referenceidentifiertype",
|
293
|
+
"referenceidtype",
|
294
|
+
"refidtype",
|
295
|
+
"relationshipidentifier",
|
296
|
+
"relationshipid",
|
297
|
+
"relationshipidentifiertype",
|
298
|
+
"relationshipidtype",
|
299
|
+
"relid",
|
300
|
+
"relidtype"].include?(normfield)
|
301
|
+
update(reference_identifier: format_reference_id(value))
|
302
|
+
end
|
303
|
+
end
|
304
|
+
return {}
|
305
|
+
end
|
306
|
+
|
307
|
+
def interpret_relationship_fields raw_data
|
308
|
+
metadata = {}
|
309
|
+
raw_data.each do |field,value|
|
310
|
+
next if value.blank? or field.blank?
|
311
|
+
field = field.to_s
|
312
|
+
|
313
|
+
next if value == field
|
314
|
+
|
315
|
+
if (split = field.split(":")).count == 2
|
316
|
+
ref_id = split.first
|
317
|
+
field = split.last.to_s
|
318
|
+
end
|
319
|
+
|
320
|
+
normfield = field.downcase.parameterize.gsub(/[_\s-]/,'')
|
321
|
+
# next unless RELATIONSHIP_FIELDS.include? normfield
|
322
|
+
|
323
|
+
# If the field specifies the object's order among siblings (usually for multiple filesets)
|
324
|
+
update(order: value.to_f) if normfield == "order"
|
325
|
+
|
326
|
+
# If the field specifies the name or ID of a collection,
|
327
|
+
# find or create the collection and update the metadata to match
|
328
|
+
if ["collection","collectiontitle","memberofcollection","collectionname", "collectionid"].include?(normfield)
|
329
|
+
col = find_or_create_collection(value)
|
330
|
+
( metadata[:member_of_collection_ids] ||= [] ) << col.id if col
|
331
|
+
end
|
332
|
+
|
333
|
+
# All variations of field names that require BulkOps::Relationship objects
|
334
|
+
next unless ["parent","parentid","parentidentifier","parentwork","child","childid","childidentifier","childwork","next","nextfile","nextwork","nextid","nextfileidentifier","nextfileid","nextworkid"].include?(normfield)
|
335
|
+
|
336
|
+
# find which type of relationship
|
337
|
+
["parent","child","next"].select{|type| normfield.include?(type)}.first
|
338
|
+
# correctly interpret the notation "id:a78C2d81"
|
339
|
+
if ((split = value.split(":")).count == 2)
|
340
|
+
ref_id = split.first
|
341
|
+
value = split.last
|
342
|
+
end
|
343
|
+
BulkOps::Relationship.create( { work_proxy_id: id,
|
344
|
+
identifier_type: ref_id || reference_identifier,
|
345
|
+
relationship_type: normfield,
|
346
|
+
object_identifier: value,
|
347
|
+
status: "new"} )
|
348
|
+
end
|
349
|
+
return metadata
|
350
|
+
end
|
351
|
+
|
352
|
+
def format_reference_id(value)
|
353
|
+
return value if value=="id"
|
354
|
+
# normalize the value string
|
355
|
+
value_method = value.titleize.gsub(/[-_\s]/,'').downcase_first_letter
|
356
|
+
# if this is a valid metadata property or solr parameter, return it as-is
|
357
|
+
return value_method if (schema.get_field?(value_method) || SolrDocument.new.respond_to?(value_method))
|
358
|
+
# if it is means to reference a row number, return the string "row"
|
359
|
+
case value.downcase.parameterize.gsub(/[_\s-]/,'')
|
360
|
+
when "row", "rownum","row number"
|
361
|
+
return "row"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def format_worktype(value)
|
366
|
+
# format the value like a class name
|
367
|
+
type = value.titleize.gsub(/[-_\s]/,'')
|
368
|
+
# reject it if it isn't a defined class
|
369
|
+
type = false unless Object.const_defined? type
|
370
|
+
# fall back to the work type defined by the operation, or a standard "Work"
|
371
|
+
return type ||= operation.work_type || "Work"
|
372
|
+
end
|
373
|
+
|
374
|
+
def format_visibility(value)
|
375
|
+
case value.downcase
|
376
|
+
when "public", "open", "true"
|
377
|
+
return "open"
|
378
|
+
when "campus", "ucsc", "institution"
|
379
|
+
return "ucsc"
|
380
|
+
when "restricted", "private", "closed", "false"
|
381
|
+
return "restricted"
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def mintLocalAuthUrl(auth_name, value)
|
386
|
+
id = value.parameterize
|
387
|
+
auth = Qa::LocalAuthority.find_or_create_by(name: auth_name)
|
388
|
+
entry = Qa::LocalAuthorityEntry.create(local_authority: auth,
|
389
|
+
label: value,
|
390
|
+
uri: id)
|
391
|
+
return localIdToUrl(id,auth_name)
|
392
|
+
end
|
393
|
+
|
394
|
+
def findAuthUrl(auth, value)
|
395
|
+
return nil if auth.nil?
|
396
|
+
return nil unless (entries = Qa::Authorities::Local.subauthority_for(auth).search(value))
|
397
|
+
entries.each do |entry|
|
398
|
+
#require exact match
|
399
|
+
if entry["label"] == value
|
400
|
+
url = entry["url"]
|
401
|
+
url ||= entry["id"]
|
402
|
+
url = localIdToUrl(url,auth) unless url =~ URI::regexp
|
403
|
+
return url
|
404
|
+
end
|
405
|
+
end
|
406
|
+
return nil
|
407
|
+
end
|
408
|
+
|
409
|
+
def localIdToUrl(id,auth_name)
|
410
|
+
return "https://digitalcollections.library.ucsc.edu/authorities/show/local/#{auth_name}/#{id}"
|
411
|
+
end
|
412
|
+
|
413
|
+
def getLocalAuth(field_name)
|
414
|
+
field = schema.get_property(field_name)
|
415
|
+
# There is only ever one local authority per field, so just pick the first you find
|
416
|
+
if vocs = field.vocabularies
|
417
|
+
vocs.each do |voc|
|
418
|
+
return voc["subauthority"] if voc["authority"].downcase == "local"
|
419
|
+
end
|
420
|
+
end
|
421
|
+
return nil
|
422
|
+
end
|
423
|
+
|
424
|
+
def setAdminSet metadata
|
425
|
+
return metadata if metadata[:admin_set_id]
|
426
|
+
asets = AdminSet.where({title: "Bulk Ingest Set"})
|
427
|
+
asets = AdminSet.find('admin_set/default') if asets.blank?
|
428
|
+
metadata[:admin_set_id] = asets.first.id unless asets.blank?
|
429
|
+
return metadata
|
430
|
+
end
|
431
|
+
|
432
|
+
def report_error type, message, **args
|
433
|
+
puts "ERROR MESSAGE: #{message}"
|
434
|
+
update(status: "error", message: message)
|
435
|
+
args[:type]=type
|
436
|
+
(@proxy_errors ||= []) << BulkOps::Error.new(**args)
|
437
|
+
end
|
438
|
+
|
439
|
+
def filename_prefix
|
440
|
+
@filename_prefix ||= operation.filename_prefix
|
441
|
+
end
|
442
|
+
|
443
|
+
def record_exists?
|
444
|
+
operation.record_exists? work_id
|
445
|
+
end
|
446
|
+
|
447
|
+
def get_removed_filesets(filestring)
|
448
|
+
file_ids = split_values(filestring)
|
449
|
+
file_ids.select{|file_id| record_exists?(file_id)}
|
450
|
+
|
451
|
+
# This part handles filenames in addition to file ids. It doesn't work yet!
|
452
|
+
# file_ids.map do |file_id|
|
453
|
+
# If the filename is the id of an existing record, keep that
|
454
|
+
# next(file_id) if (record_exists?(file_id))
|
455
|
+
# If this is the label (i.e.filename) of an existing fileset, use that fileset id
|
456
|
+
# TODO MAKE THIS WORK!!
|
457
|
+
# next(filename) if (filename_exists?(filename))
|
458
|
+
# File.join(BulkOps::Operation::INGEST_MEDIA_PATH, filename_prefix, filename)
|
459
|
+
# end
|
460
|
+
end
|
461
|
+
|
462
|
+
def delete_file_set fileset_id
|
463
|
+
BulkOps::DeleteFileSetJob.perform_later(fileset_id, operation.user.email )
|
464
|
+
end
|
465
|
+
|
466
|
+
end
|