Class: TaxonNamesController

Inherits:
ApplicationController show all
Includes:
DataControllerConfiguration::ProjectDataControllerConfiguration
Defined in:
app/controllers/taxon_names_controller.rb

Constant Summary

Constants included from ProjectsHelper

ProjectsHelper::CLASSIFIER, ProjectsHelper::CLASSIFIER_ANNOTATION

Instance Method Summary collapse

Methods included from DataControllerConfiguration::ProjectDataControllerConfiguration

#annotator_params

Methods inherited from ApplicationController

#set_time_zone

Methods included from RedirectHelper

#destroy_redirect

Methods included from RequestType

#json_request?

Methods included from LogRecent

#log_user_recent_route

Methods included from Cookies

#digest_cookie, #digested_cookie_exists?

Methods included from Whitelist

#whitelist_constantize

Methods included from ProjectsHelper

#cumulative_gb_per_year, #cumulative_projects_created_per_year, #document_cumulative_gb_per_year, #document_gb_per_year, #gb_per_year, #image_cumulative_gb_per_year, #image_gb_per_year, #invalid_object, #project_classification, #project_initials, #project_link, #project_login_link, #project_matches, #project_tag, #projects_list, #projects_search_form, #sound_cumulative_gb_per_year, #sound_gb_per_year, #taxonworks_classification, #week_in_review_graphs

Methods included from Api::Intercept

#intercept_api

Methods included from TokenAuthentication

#intercept_project, #intercept_user, #intercept_user_or_project, #project_token_authenticate, #token_authenticate

Instance Method Details

#api_catalog ⇒ Object

GET /api/v1/taxon_names/:id/inventory/catalog Contains stats block



347
348
349
350
351
352
353
354
# File 'app/controllers/taxon_names_controller.rb', line 347

def api_catalog
  @data = helpers.recursive_catalog_json(
    taxon_name: @taxon_name,
    target_depth: params[:target_depth] || 0,
    include_distribution: false
  )
  render '/taxon_names/api/v1/catalog'
end

#api_index ⇒ Object

GET /api/v1/taxon_names



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'app/controllers/taxon_names_controller.rb', line 299

def api_index
  q = ::Queries::TaxonName::Filter.new(params.merge!(api: true)).all
    .where(project_id: sessions_current_project_id)
    .order('taxon_names.id')

  respond_to do |format|
    format.json {
      @taxon_names = q.page(params[:page]).per(params[:per])
      render '/taxon_names/api/v1/index'
    }
    format.csv {
      @taxon_names = q
      send_data Export::CSV.generate_csv(
        @taxon_names,
        exclude_columns: %w{updated_by_id created_by_id project_id},
      ), type: 'text', filename: "taxon_names_#{DateTime.now}.tsv"
    }
  end
end

#api_monograph ⇒ Object

GET /api/v1/taxon_names/:id/monograph



330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'app/controllers/taxon_names_controller.rb', line 330

def api_monograph
  if helpers.extend_response_with('descendants')
    @descendants_scope = TaxonName
      .with_project_id(sessions_current_project_id)
      .find(params[:id])
      .descendants
      .order('taxon_names.id')
      .page(params[:page])
      .per(params[:per])
  else
    @taxon_name_scope = TaxonName.with_project_id(sessions_current_project_id).where(id: params[:id])
  end
  render '/taxon_names/api/v1/monograph'
end

#api_origin_citation ⇒ Object



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'app/controllers/taxon_names_controller.rb', line 390

def api_origin_citation
  q = ::Queries::TaxonName::Filter.new(params).all
    .where(project_id: sessions_current_project_id)
    .order('taxon_names.id')

  respond_to do |format|
    format.json {
      @taxon_names = q.page(params[:page]).per(params[:per])
      render '/taxon_names/origin_citation'
    }
    format.csv {
      @taxon_names = q
      send_data Export::CSV::TaxonNameOrigin.csv(
        @taxon_names,
      ).read, type: 'text', filename: "taxon_name_origin_citation_#{DateTime.now}.tsv"
    }
  end
end

#api_parse ⇒ Object



356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'app/controllers/taxon_names_controller.rb', line 356

def api_parse
  if params[:combination_id]
    @combination = Combination
      .where(project_id: sessions_current_project_id)
      .find(params[:combination_id])
  end
  @result = Vendor::Biodiversity::Result.new(
    query_string: params.require(:query_string),
    project_id: sessions_current_project_id,
    code: :iczn # !! TODO: generalize
  ).result
  render '/taxon_names/api/v1/parse'
end

#api_show ⇒ Object

GET /api/v1/taxon_names/:id



320
321
322
# File 'app/controllers/taxon_names_controller.rb', line 320

def api_show
  render '/taxon_names/api/v1/show'
end

#api_summary ⇒ Object

GET /api/v1/taxon_names/:id/inventory/summary



325
326
327
# File 'app/controllers/taxon_names_controller.rb', line 325

def api_summary
  render '/taxon_names/api/v1/summary'
end

#autocomplete ⇒ Object



98
99
100
101
102
103
104
105
# File 'app/controllers/taxon_names_controller.rb', line 98

def autocomplete
  render json: {} and return if params[:term].blank?
  @taxon_names = ::Queries::TaxonName::Autocomplete.new(
    params[:term],
    exact: 'true',
    **autocomplete_params
  ).autocomplete
end

#autocomplete_params ⇒ Object (private)



472
473
474
475
476
477
# File 'app/controllers/taxon_names_controller.rb', line 472

def autocomplete_params
  params.permit(
    :valid, :exact, :no_leaves,
    type: [], parent_id: [], nomenclature_group: []
  ).to_h.symbolize_keys.merge(project_id: sessions_current_project_id)
end

#autoselect ⇒ Object

GET /taxon_names/autoselect



410
411
412
413
414
415
416
417
418
# File 'app/controllers/taxon_names_controller.rb', line 410

def autoselect
  render json: ::Autoselect::TaxonName::Autoselect.new(
    term: params[:term],
    level: params[:level],
    project_id: sessions_current_project_id,
    user_id: sessions_current_user_id,
    **autoselect_params
  ).response
end

#autoselect_col_create ⇒ Object

POST



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'app/controllers/taxon_names_controller.rb', line 427

def autoselect_col_create
  result = ::Autoselect::TaxonName::CatalogueOfLifeCreator.new(
    rows: autoselect_col_create_params,
    col_code: params[:col_code],
    project_id: sessions_current_project_id,
    user_id: sessions_current_user_id
  ).call
  tn = ::TaxonName.find(result[:taxon_name_id])
  render json: result.merge(global_id: tn.to_global_id.to_s)
rescue ::Autoselect::TaxonName::CatalogueOfLifeCreator::CreationError => e
  render json: {
    error: e.message,
    failed_col_name: e.col_name,
    failed_col_id: e.col_id
  }, status: :unprocessable_entity
end

#autoselect_col_create_params ⇒ Object (private)



446
447
448
449
450
451
452
453
454
455
# File 'app/controllers/taxon_names_controller.rb', line 446

def autoselect_col_create_params
  params.permit(
    rows: [
      :col_name, :col_rank, :col_id, :dataset_id, :taxonworks_id,
      :col_authorship, :col_year, :col_status
    ]
  )
    .fetch(:rows, [])
    .map(&:to_h)
end

#autoselect_col_datasets ⇒ Object

GET /taxon_names/col_datasets?q=...



421
422
423
424
# File 'app/controllers/taxon_names_controller.rb', line 421

def autoselect_col_datasets
  results = ::Vendor::Colrapi.datasets(q: params[:q].to_s, limit: 20)
  render json: results
end

#autoselect_params ⇒ Object (private)



457
458
459
460
461
462
# File 'app/controllers/taxon_names_controller.rb', line 457

def autoselect_params
  params.permit(
    :valid, :exact, :no_leaves, :dataset_id, :show_info,
    type: [], parent_id: [], nomenclature_group: []
  ).to_h.symbolize_keys
end

#batch_load ⇒ Object



118
119
# File 'app/controllers/taxon_names_controller.rb', line 118

def batch_load
end

#batch_params ⇒ Object (private)



510
511
512
513
514
515
516
517
518
519
520
# File 'app/controllers/taxon_names_controller.rb', line 510

def batch_params
  params.permit(
    :file,
    :parent_taxon_name_id,
    :nomenclature_code,
    :also_create_otu,
    :import_level).merge(
      user_id: sessions_current_user_id,
      project_id: sessions_current_project_id
    ).to_h.symbolize_keys
end

#batch_update ⇒ Object

PATCH /taxon_names/batch_update.json?taxon_names_query=<>&taxon_name=taxon_name_id=123}



285
286
287
288
289
290
291
292
293
294
295
296
# File 'app/controllers/taxon_names_controller.rb', line 285

def batch_update
  if r = Protonym.batch_update(
      preview: params[:preview],
      taxon_name: taxon_name_params.merge(by: sessions_current_user_id),
      taxon_name_query: params[:taxon_name_query].merge(by: sessions_current_user_id),
      user_id: sessions_current_user_id,
      project_id: sessions_current_project_id)
    render json: r.to_json, status: :ok
  else
    render json: {}, status: :unprocessable_content
  end
end

#create ⇒ Object

POST /taxon_names POST /taxon_names.json



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/taxon_names_controller.rb', line 40

def create
  @taxon_name = TaxonName.new(taxon_name_params)
  respond_to do |format|
    if @taxon_name.save
      format.html { redirect_to url_for(@taxon_name.metamorphosize),
                    notice: "Taxon name '#{@taxon_name.name}' was successfully created." }
      format.json { render :show, status: :created, location: @taxon_name.metamorphosize }
    else
      format.html { render action: :new }
      format.json { render json: @taxon_name.errors, status: :unprocessable_content }
    end
  end
end

#create_nomen_batch_load ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'app/controllers/taxon_names_controller.rb', line 213

def create_nomen_batch_load
  if params[:file] && digested_cookie_exists?(params[:file].tempfile, :nomen_taxon_names_md5)
    @result = BatchLoad::Import::TaxonNames::NomenInterpreter.new(**batch_params)
    if @result.create
      flash[:notice] = "Successfully proccessed file, #{@result.total_records_created} items were created."
      render 'taxon_names/batch_load/nomen/create' and return
    else
      flash[:alert] = 'Batch import failed.'
    end
  else
    flash[:alert] = 'File to batch upload must be supplied.'
  end
  render :batch_load
end

#create_simple_batch_load ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/controllers/taxon_names_controller.rb', line 185

def create_simple_batch_load

  if params[:file] && digested_cookie_exists?(params[:file].tempfile, :simple_taxon_names_md5)
    @result = BatchLoad::Import::TaxonifiToTaxonworks.new(**batch_params)
    if @result.create
      flash[:notice] = "Successfully proccessed file, #{@result.total_records_created} taxon names were created."
      render 'taxon_names/batch_load/simple/create' and return
    else
      flash[:alert] = 'Batch import failed.'
    end
  else
    flash[:alert] = 'File to batch upload must be supplied.'
  end

  render :batch_load
end

#destroy ⇒ Object

DELETE /taxon_names/1 DELETE /taxon_names/1.json



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/controllers/taxon_names_controller.rb', line 74

def destroy
  parent_id = @taxon_name.parent_id
  @taxon_name.destroy
  respond_to do |format|
    if @taxon_name.destroyed?
      format.html { destroy_redirect @taxon_name, notice: 'TaxonName was successfully destroyed.' }
      format.json {
        render json: { parent_id: }
      }
    else
      format.html { destroy_redirect @taxon_name, notice: 'TaxonName was not destroyed, ' + @taxon_name.errors.full_messages.join('; ') }
      format.json { render json: @taxon_name.errors, status: :unprocessable_content }
    end
  end
end

#download ⇒ Object

GET /taxon_names/download



112
113
114
115
116
# File 'app/controllers/taxon_names_controller.rb', line 112

def download
  send_data Export::CSV.generate_csv(
    TaxonName.where(project_id: sessions_current_project_id)
  ), type: 'text', filename: "taxon_names_#{DateTime.now}.tsv"
end

#edit ⇒ Object

GET /taxon_names/1/edit



35
36
# File 'app/controllers/taxon_names_controller.rb', line 35

def edit
end

#index ⇒ Object

GET /taxon_names GET /taxon_names.json



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'app/controllers/taxon_names_controller.rb', line 10

def index
  respond_to do |format|
    format.html do
      @recent_objects = TaxonName.recent_from_project_id(sessions_current_project_id).order(updated_at: :desc).limit(10)
      render '/shared/data/all/index'
    end
    format.json {
      @taxon_names = ::Queries::TaxonName::Filter.new(params).all
      .page(params[:page])
      .per(params[:per])
    }
  end
end

#list ⇒ Object



107
108
109
# File 'app/controllers/taxon_names_controller.rb', line 107

def list
  @taxon_names = TaxonName.with_project_id(sessions_current_project_id).order(:id).page(params[:page])
end

#match ⇒ Object

POST /taxon_names/match.json subgenus_matching - 'with' (default): match names as given; 'without':

if that fails, retry ignoring subgenus; 'both': always try both, so
different taxa matched each way are reported as ambiguous


250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'app/controllers/taxon_names_controller.rb', line 250

def match
  names = match_params[:names] || []
  project_id = sessions_current_project_id
  taxon_name_id = match_params[:taxon_name_id]
  subgenus_matching = match_params[:subgenus_matching]

  tn_results = Match::Otu::TaxonName.new(
    names:,
    project_id:,
    levenshtein_distance: match_params[:levenshtein_distance] || 0,
    taxon_name_id:,
    resolve_synonyms: match_params[:resolve_synonyms] == 'true',
    try_without_subgenus: %w{without both}.include?(subgenus_matching),
    try_without_subgenus_after_exact_match: subgenus_matching == 'both'
  ).call

  @result = if match_params[:match_otu_names] == 'true'
    otu_results = Match::Otu::MorphospeciesName.new(
      names:, project_id:, taxon_name_id:
    ).call
    Match::Otu::MergeResults.new(tn_results:, otu_results:).call
  else
    tn_results.map { |r|
      r.merge(match_source: r[:matched] ? 'taxon_name' : nil)
    }
  end

  render :match
end

#match_params ⇒ Object (private)



479
480
481
482
483
484
485
486
487
488
# File 'app/controllers/taxon_names_controller.rb', line 479

def match_params
  params.permit(
    :levenshtein_distance,
    :taxon_name_id,
    :resolve_synonyms,
    :subgenus_matching,
    :match_otu_names,
    names: []
  )
end

#new ⇒ Object

GET /taxon_names/new



30
31
32
# File 'app/controllers/taxon_names_controller.rb', line 30

def new
  @taxon_name = Protonym.new(source: Source.new)
end

#origin_citation ⇒ Object

GET /api/v1/taxon_names



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'app/controllers/taxon_names_controller.rb', line 371

def origin_citation
  q = ::Queries::TaxonName::Filter.new(params).all
    .where(project_id: sessions_current_project_id)
    .order('taxon_names.id')

  respond_to do |format|
    format.json {
      @taxon_names = q.page(params[:page]).per(params[:per])
      render '/taxon_names/origin_citation'
    }
    format.csv {
      @taxon_names = q
      send_data Export::CSV::TaxonNameOrigin.csv(
        @taxon_names,
      ).read, type: 'text', filename: "taxon_name_origin_citation_#{DateTime.now}.tsv"
    }
  end
end

#original_combination ⇒ Object

GET /taxon_names/1/original_combination



281
282
# File 'app/controllers/taxon_names_controller.rb', line 281

def original_combination
end

#parse ⇒ Object



228
229
230
231
232
233
234
235
236
237
238
239
# File 'app/controllers/taxon_names_controller.rb', line 228

def parse
  if params[:combination_id]
    @combination = Combination
      .where(project_id: sessions_current_project_id)
      .find(params[:combination_id])
  end
  @result = Vendor::Biodiversity::Result.new(
    query_string: params.require(:query_string),
    project_id: sessions_current_project_id,
    code: :iczn # !! TODO: generalize
  ).result
end

#predicted_rank ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/controllers/taxon_names_controller.rb', line 125

def predicted_rank
  if params[:parent_id]
    p = TaxonName.find_by(id: params[:parent_id])
    if p.nil?
      render json: {predicted_rank: ''}.to_json
    else
      render json: {predicted_rank: p.predicted_child_rank(params[:name]).to_s}.to_json
    end
  else
    render json: {predicted_rank: ''}.to_json
  end
end

#preview_nomen_batch_load ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'app/controllers/taxon_names_controller.rb', line 202

def preview_nomen_batch_load
  if params[:file]
    @result = BatchLoad::Import::TaxonNames::NomenInterpreter.new(**batch_params)
    digest_cookie(params[:file].tempfile, :nomen_taxon_names_md5)
    render 'taxon_names/batch_load/nomen/preview'
  else
    flash[:notice] = 'No file provided!'
    redirect_to action: :batch_load
  end
end

#preview_simple_batch_load ⇒ Object



174
175
176
177
178
179
180
181
182
183
# File 'app/controllers/taxon_names_controller.rb', line 174

def preview_simple_batch_load
  if params[:file]
    @result = BatchLoad::Import::TaxonifiToTaxonworks.new(**batch_params)
    digest_cookie(params[:file].tempfile, :simple_taxon_names_md5)
    render 'taxon_names/batch_load/simple/preview'
  else
    flash[:notice] = 'No file provided!'
    redirect_to action: :batch_load
  end
end

#random ⇒ Object



138
139
140
141
142
# File 'app/controllers/taxon_names_controller.rb', line 138

def random
  redirect_to browse_nomenclature_task_path(
    taxon_name_id: TaxonName.where(project_id: sessions_current_project_id).order('random()').limit(1).pick(:id)
  )
end

#rank_table ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'app/controllers/taxon_names_controller.rb', line 144

def rank_table
  @query = ::Queries::TaxonName::Tabular.new(
    taxon_name_id: params.require(:taxon_name_id), # this is one of the few places
    ranks: params.require(:ranks),
    fieldsets: params[:fieldsets],
    limit: params[:limit],
    validity: params[:validity],
    combinations: params[:combinations],
    project_id: sessions_current_project_id,
    rank_data: params[:rank_data],
    descriptors_scored_for_otu: params[:descriptors_scored_for_otu],
    otu_observation_count: params[:otu_observation_count],
    otu_observation_depictions: params[:otu_observation_depictions],
    otus: params[:otus]
  )
end

#ranks ⇒ Object



121
122
123
# File 'app/controllers/taxon_names_controller.rb', line 121

def ranks
  render json: RANKS_JSON.to_json
end

#remove_authors ⇒ Object



241
242
243
244
# File 'app/controllers/taxon_names_controller.rb', line 241

def remove_authors
  names = TaxonName.remove_authors(params['names'].first(5000))
  render json: { names: }
end

#search ⇒ Object



90
91
92
93
94
95
96
# File 'app/controllers/taxon_names_controller.rb', line 90

def search
  if params[:id].blank?
    redirect_to taxon_names_path, alert: 'You must select an item from the list with a click or tab press before clicking show.'
  else
    redirect_to taxon_name_path(params[:id])
  end
end

#select_options ⇒ Object

GET /taxon_names/select_options



166
167
168
169
170
171
172
# File 'app/controllers/taxon_names_controller.rb', line 166

def select_options
  @taxon_names = TaxonName.select_optimized(
    sessions_current_user_id,
    sessions_current_project_id,
    target: params[:target]
  )
end

#set_taxon_name ⇒ Object (private)



464
465
466
467
468
469
470
# File 'app/controllers/taxon_names_controller.rb', line 464

def set_taxon_name
  @taxon_name = TaxonName
    .with_project_id(sessions_current_project_id)
    .includes(:creator, :updater)
    .find(params[:id])
  @recent_object = @taxon_name
end

#show ⇒ Object

GET /taxon_names/1 GET /taxon_names/1.json



26
27
# File 'app/controllers/taxon_names_controller.rb', line 26

def show
end

#taxon_name_params ⇒ Object (private)



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'app/controllers/taxon_names_controller.rb', line 490

def taxon_name_params
  params.require(:taxon_name).permit(
    :name,
    :parent_id,
    :year_of_publication,
    :etymology,
    :verbatim_author, :verbatim_name, :rank_class, :type, :masculine_name,
    :feminine_name, :neuter_name, :also_create_otu,
    roles_attributes: [
      :id, :_destroy, :type, :person_id, :position,
      person_attributes: [
        :last_name, :first_name, :suffix, :prefix
      ]
    ],
    family_group_name_form_relationship_attributes: [:id, :_destroy, :object_taxon_name_id],
    origin_citation_attributes: [:id, :_destroy, :source_id, :pages],
    taxon_name_classifications_attributes: [:id, :_destroy, :type]
  )
end

#taxonomy ⇒ Object



161
162
163
# File 'app/controllers/taxon_names_controller.rb', line 161

def taxonomy
  @taxon_name = TaxonName.find(params[:id])
end

#update ⇒ Object

PATCH/PUT /taxon_names/1 PATCH/PUT /taxon_names/1.json



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/controllers/taxon_names_controller.rb', line 56

def update
  respond_to do |format|
    if @taxon_name.update(taxon_name_params)

      # TODO: WHY?!
      @taxon_name.reload

      format.html { redirect_to url_for(@taxon_name.metamorphosize), notice: 'Taxon name was successfully updated.' }
      format.json { render :show, status: :ok, location: @taxon_name.metamorphosize }
    else
      format.html { render action: :edit }
      format.json { render json: @taxon_name.errors, status: :unprocessable_content }
    end
  end
end