Class: Specify::Service::StubGenerator

Inherits:
Service
  • Object
show all
Defined in:
lib/specify/services/stub_generator.rb

Overview

A StubGenerator creates Specify::Model::CollectionObject stub records (mostly empty records with a minmum of information) in collection in a Specify::Database.

Instance Attribute Summary collapse

Attributes inherited from Service

#agent, #collection, #discipline, #division, #session

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Service

#database

Constructor Details

#initialize(collection:, config:, host:, database:, specify_user: nil) {|_self| ... } ⇒ StubGenerator

Returns a new StubGenerator.

Yields:

  • (_self)

Yield Parameters:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/specify/services/stub_generator.rb', line 120

def initialize(collection:,
               config:,
               host:,
               database:,
               specify_user: nil)
  super
  @accession = nil
  @cataloger = agent
  @collecting_geography = nil
  @collecting_locality = nil
  @default_locality_name = 'not cataloged, see label'
  @dataset_name = "stub record set #{Time.now}"
  @preparation_type = nil
  @preparation_count = nil
  @record_set = nil
  @taxon = nil
  yield(self) if block_given?
end

Instance Attribute Details

#accessionObject

An existing Specify::Model::Accession.



10
11
12
# File 'lib/specify/services/stub_generator.rb', line 10

def accession
  @accession
end

#catalogerObject

An existing Specify::Model::Agent.



13
14
15
# File 'lib/specify/services/stub_generator.rb', line 13

def cataloger
  @cataloger
end

#collecting_geographyObject (readonly)

An existing Specify::Model::GeographicName.



16
17
18
# File 'lib/specify/services/stub_generator.rb', line 16

def collecting_geography
  @collecting_geography
end

#collecting_localityObject (readonly)

An existing Specify::Model::Locality.



19
20
21
# File 'lib/specify/services/stub_generator.rb', line 19

def collecting_locality
  @collecting_locality
end

#dataset_nameObject

String; the name for the #record_set that will be created for the generated Specify::Model::CollectionObject records.



23
24
25
# File 'lib/specify/services/stub_generator.rb', line 23

def dataset_name
  @dataset_name
end

#default_locality_nameObject

String; the name of the Specify::Model::Locality that will be created if no existing Specify::Model::Locality is passed via #collecting_data=.



27
28
29
# File 'lib/specify/services/stub_generator.rb', line 27

def default_locality_name
  @default_locality_name
end

#preparation_countObject (readonly)

Integer. See Specify::Model::Preparation#count.



30
31
32
# File 'lib/specify/services/stub_generator.rb', line 30

def preparation_count
  @preparation_count
end

#preparation_typeObject (readonly)

An existing Specify::Model::PreparationType.



33
34
35
# File 'lib/specify/services/stub_generator.rb', line 33

def preparation_type
  @preparation_type
end

#record_setObject (readonly)

A Specify::Model::RecordSet.



36
37
38
# File 'lib/specify/services/stub_generator.rb', line 36

def record_set
  @record_set
end

#taxonObject (readonly)

An existing Specify::Model::Taxon.



39
40
41
# File 'lib/specify/services/stub_generator.rb', line 39

def taxon
  @taxon
end

Class Method Details

.load_yaml(file) ⇒ Object

Returns a new StubGenerator with attributes from a YAML file.

file should have the structure:

---
:stub_generator:
  :host: <hostname>
  :database: <database name>
  :collection: <collection name>
  :config: <database configuration file>
dataset_name: <record set name>
accession: <accession number>
cataloger: <specify user name>
collecting_data:
  <1st rank>: <name>
  <2nd rank>: <name>
  <3rd rank>: <name>
  :locality: <name>
default_locality_name: <name>
determination:
  <1st rank>: <name>
  <2nd rank>: <name>
  <3rd rank>: <name>
preparation:
  :type: <preparation type>
  :count: <preparation count>

Items prefixed with : in the example above will be deserialized as Ruby symbols and need to be prefixed with : in the file. Leave out any items that are not to be set. The section :stub_generator: is required.



71
72
73
# File 'lib/specify/services/stub_generator.rb', line 71

def self.load_yaml(file)
  unwrap Psych.load_file(file)
end

.unwrap(hash) ⇒ Object

Returns a new StubGenerator with attributes from hash.

hash should have the structure {

stub_generator: {
  host: <hostname>,
  database: <database name>,
  collection: <collection name>,
  config: <database configuration file>
},
dataset_name => <record set name>,
accession => <accession number>,
cataloger => <specify user name>,
collecting_data => {
  <1st rank> => <name>,
  <2nd rank> => <name>,
  <3rd rank> => <name>,
  locality: <name>
},
default_locality_name => <name>,
determination => {
  <1st rank> => <name>,
  <2nd rank> => <name>,
  <3rd rank> => <name>
},
preparation => {
  type: <preparation type>,
  count: <preparation count>
}

} Items that are symbols in the example above need to be symbols in the hash passed. Leave out any items that are not to be set. The key :stub_generator is required.



108
109
110
111
112
113
114
115
116
117
# File 'lib/specify/services/stub_generator.rb', line 108

def self.unwrap(hash)
  new hash.delete(:stub_generator) do |stubs|
    hash.each do |key, value|
      setter = (key + '=').to_sym
      puts "#{setter}#{value}"
      next unless value
      stubs.public_send(setter, value)
    end
  end
end

Instance Method Details

#collecting_data=(vals) ⇒ Object

Sets #collecting_geography and #collecting_locality.

vals is a Hash with the structure { 'rank' => 'name', :locality => 'name' } where rank is an existing Specify::Model::AdministrativeDivision#name, name an existing Specify::Model::GeographicName#name with that rank. :locality is not a geographic rank and must be given as a symbol. When traversing a tree hierarchy, give key value paris in descencing order of rank:

{ 'Country' => 'United States',
  'State' => 'Kansas',
  'County' => 'Douglas County',
  :locality => 'Freestate Brewery' }


166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/specify/services/stub_generator.rb', line 166

def collecting_data=(vals)
  locality = vals.delete :locality
  unless vals.empty?
    @collecting_geography = geography.search_tree(vals)
    unless @collecting_geography
      missing_geo = vals.values.join(', ')
      raise GEOGRAPHY_NOT_FOUND_ERROR + missing_geo
    end
  end
  return unless locality
  @collecting_locality = find_locality locality
  raise LOCALITY_NOT_FOUND_ERROR + locality unless collecting_locality
end

#collecting_locality!Object

Returns #collecting_locality or #default_locality if #collecting_locality is nil but #collecting_geography is not; Will create the Specify::Model::GeographicName for #default_locality if it does not exist in #localities.



184
185
186
187
188
# File 'lib/specify/services/stub_generator.rb', line 184

def collecting_locality!
  return collecting_locality if collecting_locality
  return unless collecting_geography
  default_locality!
end

#create(count) ⇒ Object

Creates count records for Specify::Model::CollectionObject with the attributes of self.



192
193
194
195
196
197
198
199
# File 'lib/specify/services/stub_generator.rb', line 192

def create(count)
  @record_set = collection.add_record_set Name: dataset_name,
                                          user: cataloger.user
  count.times do
    stub = create_stub
    @record_set.add_record_set_item collection_object: stub
  end
end

#default_localityObject

Returns the Specify::Model::GeographicName for #default locality if it exists.



203
204
205
# File 'lib/specify/services/stub_generator.rb', line 203

def default_locality
  find_locality default_locality_name
end

#default_locality!Object

Returns the Specify::Model::GeographicName for #default locality. Creates the record if it does not exist in #localities.



209
210
211
212
213
214
# File 'lib/specify/services/stub_generator.rb', line 209

def default_locality!
  return default_locality if default_locality
  default_locality ||
    discipline.add_locality(LocalityName: default_locality_name,
                            geographic_name: collecting_geography)
end

#determination=(vals) ⇒ Object

Sets #taxon, to which stub records will be determined. vals is a Hash with the structure { 'rank' => 'name' } where rank is an existing Specify::Model::Rank#name, name an existing Specify::Model::Taxon#name with that rank. When traversing a tree hierarchy, give key value paris in descencing order of rank:

{ 'Phylum' => 'Arthropoda',
  'Class' => 'Trilobita',
  'Order' => 'Asaphida',
  'Family' => 'Asaphidae' }


225
226
227
228
# File 'lib/specify/services/stub_generator.rb', line 225

def determination=(vals)
  @taxon = taxonomy.search_tree vals
  raise TAXON_NOT_FOUND_ERROR + vals.to_s unless taxon
end

#find_locality(locality_name) ⇒ Object

Returns the Specify::Model::Locality for locality_name in #localities.



231
232
233
234
235
# File 'lib/specify/services/stub_generator.rb', line 231

def find_locality(locality_name)
  locality_matches = localities.where LocalityName: locality_name
  raise Model::AMBIGUOUS_MATCH_ERROR if locality_matches.count > 1
  locality_matches.first
end

#generatedObject

Returns the Specify::Model::CollectionObject records in #record_set (the records created by #create).



239
240
241
# File 'lib/specify/services/stub_generator.rb', line 239

def generated
  record_set&.collection_objects
end

#geographyObject

Returns the Specify::Model::Geography for #discipline.



244
245
246
# File 'lib/specify/services/stub_generator.rb', line 244

def geography
  discipline.geography
end

#localitiesObject

Returns a Sequel::Dataset of Specify::Model::Locality records in #collecting_geography or #division if #collecting_geography is nil.



250
251
252
253
# File 'lib/specify/services/stub_generator.rb', line 250

def localities
  @collecting_geography&.localities_dataset ||
    discipline.localities_dataset
end

#preparation=(type:, count: nil) ⇒ Object

Sets #preparation_type and #preparation_count. type must be an existing Specify::Model::PreparationType#name. count should be an Integer.

Returns an array with the #preparation_type and #preparation_count.



260
261
262
263
264
265
266
# File 'lib/specify/services/stub_generator.rb', line 260

def preparation=(type:, count: nil)
  @preparation_type = collection.preparation_types_dataset
                                .first Name: type
  raise PREPTYPE_NOT_FOUND_ERROR + type unless preparation_type
  @preparation_count = count
  [preparation_type, preparation_count].compact
end

#taxonomyObject

Returns the Specify::Model::Taxonomy for #discipline.



269
270
271
# File 'lib/specify/services/stub_generator.rb', line 269

def taxonomy
  discipline.taxonomy
end