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



338
339
340
341
342
343
# File 'app/controllers/taxon_names_controller.rb', line 338

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



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'app/controllers/taxon_names_controller.rb', line 291

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



322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'app/controllers/taxon_names_controller.rb', line 322

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



375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'app/controllers/taxon_names_controller.rb', line 375

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



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

def api_parse
  @combination = Combination.where(project_id: sessions_current_project_id).find(params[:combination_id]) if params[:combination_id]
  @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



312
313
314
# File 'app/controllers/taxon_names_controller.rb', line 312

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

#api_summary ⇒ Object

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



317
318
319
# File 'app/controllers/taxon_names_controller.rb', line 317

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)



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

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



395
396
397
398
399
400
401
402
403
# File 'app/controllers/taxon_names_controller.rb', line 395

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



412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'app/controllers/taxon_names_controller.rb', line 412

def autoselect_col_create
  result = ::Autoselect::TaxonName::ColCreator.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::ColCreator::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)



431
432
433
434
435
# File 'app/controllers/taxon_names_controller.rb', line 431

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=...



406
407
408
409
# File 'app/controllers/taxon_names_controller.rb', line 406

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

#autoselect_params ⇒ Object (private)



437
438
439
440
441
442
# File 'app/controllers/taxon_names_controller.rb', line 437

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)



487
488
489
490
491
492
493
494
495
496
497
# File 'app/controllers/taxon_names_controller.rb', line 487

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}



277
278
279
280
281
282
283
284
285
286
287
288
# File 'app/controllers/taxon_names_controller.rb', line 277

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


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'app/controllers/taxon_names_controller.rb', line 246

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)



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

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



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

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



273
274
# File 'app/controllers/taxon_names_controller.rb', line 273

def original_combination
end

#parse ⇒ Object



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

def parse
  @combination = Combination.where(project_id: sessions_current_project_id).find(params[:combination_id]) if params[:combination_id]
  @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



237
238
239
240
# File 'app/controllers/taxon_names_controller.rb', line 237

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)



444
445
446
447
# File 'app/controllers/taxon_names_controller.rb', line 444

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)



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# File 'app/controllers/taxon_names_controller.rb', line 467

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