inat-get 0.8.0.12 → 0.8.0.13

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/bin/inat-get +1 -1
  4. data/inat-get.gemspec +6 -6
  5. data/lib/extra/enum.rb +4 -0
  6. data/lib/extra/period.rb +15 -0
  7. data/lib/inat/app/application.rb +4 -3
  8. data/lib/inat/app/config/messagelevel.rb +3 -1
  9. data/lib/inat/app/config/shiftage.rb +1 -1
  10. data/lib/inat/app/config/updatemode.rb +1 -1
  11. data/lib/inat/app/config.rb +6 -2
  12. data/lib/inat/app/globals.rb +6 -3
  13. data/lib/inat/app/info.rb +18 -13
  14. data/lib/inat/app/logging.rb +3 -3
  15. data/lib/inat/app/preamble.rb +1 -1
  16. data/lib/inat/app/status.rb +3 -9
  17. data/lib/inat/app/task/context.rb +8 -4
  18. data/lib/inat/app/task/dsl.rb +5 -3
  19. data/lib/inat/app/task.rb +2 -2
  20. data/lib/inat/data/api.rb +210 -181
  21. data/lib/inat/data/db.rb +9 -4
  22. data/lib/inat/data/ddl.rb +24 -5
  23. data/lib/inat/data/entity/comment.rb +8 -4
  24. data/lib/inat/data/entity/flag.rb +7 -3
  25. data/lib/inat/data/entity/identification.rb +9 -4
  26. data/lib/inat/data/entity/observation.rb +27 -14
  27. data/lib/inat/data/entity/observationphoto.rb +7 -3
  28. data/lib/inat/data/entity/observationsound.rb +6 -7
  29. data/lib/inat/data/entity/photo.rb +9 -3
  30. data/lib/inat/data/entity/place.rb +11 -2
  31. data/lib/inat/data/entity/project.rb +16 -10
  32. data/lib/inat/data/entity/projectadmin.rb +4 -4
  33. data/lib/inat/data/entity/projectobservationrule.rb +3 -4
  34. data/lib/inat/data/entity/request.rb +7 -3
  35. data/lib/inat/data/entity/sound.rb +7 -2
  36. data/lib/inat/data/entity/taxon.rb +11 -3
  37. data/lib/inat/data/entity/user.rb +7 -3
  38. data/lib/inat/data/entity/vote.rb +7 -3
  39. data/lib/inat/data/entity.rb +38 -24
  40. data/lib/inat/data/enums/conservationstatus.rb +3 -3
  41. data/lib/inat/data/enums/geoprivacy.rb +3 -1
  42. data/lib/inat/data/enums/iconictaxa.rb +1 -1
  43. data/lib/inat/data/enums/identificationcategory.rb +1 -1
  44. data/lib/inat/data/enums/licensecode.rb +5 -2
  45. data/lib/inat/data/enums/projectadminrole.rb +1 -1
  46. data/lib/inat/data/enums/projecttype.rb +5 -3
  47. data/lib/inat/data/enums/qualitygrade.rb +1 -1
  48. data/lib/inat/data/enums/rank.rb +1 -1
  49. data/lib/inat/data/model.rb +73 -24
  50. data/lib/inat/data/query.rb +14 -9
  51. data/lib/inat/data/sets/dataset.rb +9 -5
  52. data/lib/inat/data/sets/list.rb +8 -3
  53. data/lib/inat/data/sets/listers.rb +10 -5
  54. data/lib/inat/data/sets/wrappers.rb +79 -75
  55. data/lib/inat/data/types/location.rb +17 -8
  56. data/lib/inat/data/types/std.rb +171 -176
  57. data/lib/inat/report/report_dsl.rb +13 -11
  58. data/lib/inat/report/table.rb +7 -3
  59. data/lib/inat/utils/deep.rb +25 -19
  60. metadata +5 -5
  61. data/lib/inat/data/cache.rb +0 -9
@@ -3,12 +3,17 @@
3
3
  require_relative '../app/globals'
4
4
  require_relative 'types/std'
5
5
 
6
- autoload :Entity, 'inat/data/entity'
6
+ module INat::Data
7
+ autoload :Entity, 'inat/data/entity'
8
+ end
9
+
10
+ module INat::Data; end
7
11
 
8
- class Model
12
+ class INat::Data::Model
9
13
 
10
- include LogDSL
14
+ include INat::App::Logger::DSL
11
15
 
16
+ # @private
12
17
  class Field
13
18
 
14
19
  attr_reader :model, :name, :type, :id_field
@@ -42,7 +47,10 @@ class Model
42
47
 
43
48
  end
44
49
 
45
- class ScalarField < Model::Field
50
+ # @private
51
+ class ScalarField < Field
52
+
53
+ using INat::Types::Std
46
54
 
47
55
  attr_reader :index, :unique, :primary_key
48
56
 
@@ -51,7 +59,7 @@ class Model
51
59
  end
52
60
 
53
61
  def initialize model, name, type, id_field, required, index, unique, primary_key
54
- if Class === type && Entity > type && id_field == nil
62
+ if Class === type && INat::Data::Entity > type && id_field == nil
55
63
  id_field = "#{ name }_id".intern
56
64
  end
57
65
  super model, name, type, id_field
@@ -74,7 +82,7 @@ class Model
74
82
  md.define_method "#{ ni }=" do |value|
75
83
  prevalue = instance_variable_get "@#{ ni }"
76
84
  if prevalue != value
77
- debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon'
85
+ debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon'
78
86
  instance_variable_set "@#{ ni }", value
79
87
  instance_variable_set "@saved", false
80
88
  end
@@ -92,7 +100,7 @@ class Model
92
100
  md.define_method "#{ nm }=" do |value|
93
101
  prevalue = instance_variable_get "@#{ ni }"
94
102
  if prevalue != value&.id
95
- debug "ASS: #{ self.id }: #{ nm } / #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon'
103
+ debug "ASS: #{ self.id }: #{ nm } / #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon'
96
104
  instance_variable_set "@#{ ni }", value&.id
97
105
  instance_variable_set "@saved", false
98
106
  end
@@ -105,7 +113,7 @@ class Model
105
113
  raise TypeError, "Invalid '#{ nm }' value: #{ value.inspect }!", caller unless tp === value || (value == nil && !rq)
106
114
  prevalue = instance_variable_get "@#{ nm }"
107
115
  if prevalue != value
108
- debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon'
116
+ debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon'
109
117
  instance_variable_set "@#{ nm }", value
110
118
  instance_variable_set "@saved", false
111
119
  end
@@ -207,7 +215,10 @@ class Model
207
215
 
208
216
  end
209
217
 
210
- class ArrayField < Model::Field
218
+ # @private
219
+ class ArrayField < Field
220
+
221
+ using INat::Types::Std
211
222
 
212
223
  attr_reader :back_field
213
224
 
@@ -223,7 +234,7 @@ class Model
223
234
  raise ArgumentError, "Argument 'id_field' is required for name '#{ name }'!", caller[1..]
224
235
  end
225
236
  end
226
- back_field = "#{ model.name.downcase }_id".intern if back_field == nil
237
+ back_field = "#{ model.short_name.downcase }_id".intern if back_field == nil
227
238
  super model, name, type, id_field
228
239
  @owned = owned
229
240
  @back_field = back_field
@@ -248,7 +259,7 @@ class Model
248
259
  value = value&.sort.uniq
249
260
  end
250
261
  if prevalue != value
251
- debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.name == 'Taxon'
262
+ debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.short_name == 'Taxon'
252
263
  instance_variable_set "@#{ ni }", value
253
264
  instance_variable_set "@saved", false
254
265
  end
@@ -274,7 +285,7 @@ class Model
274
285
  end
275
286
  prevalue = instance_variable_get("@#{ nm }")
276
287
  if prevalue&.sort != value&.sort
277
- debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.name == 'Taxon'
288
+ debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.short_name == 'Taxon'
278
289
  instance_variable_set "@#{ nm }", value
279
290
  instance_variable_set "@saved", false
280
291
  end
@@ -292,13 +303,16 @@ class Model
292
303
 
293
304
  end
294
305
 
295
- class ManyToManyField < Model::ArrayField
306
+ # @private
307
+ class ManyToManyField < ArrayField
308
+
309
+ using INat::Types::Std
296
310
 
297
311
  attr_reader :table_name, :link_field, :index
298
312
 
299
313
  def initialize model, name, type, id_field, owned, table_name, back_field, link_field, index
300
- table_name = "#{ model.name.downcase }_#{ name }".intern if table_name == nil
301
- link_field = "#{ type.name.downcase }_id".intern if link_field == nil
314
+ table_name = "#{ model.short_name.downcase }_#{ name }".intern if table_name == nil
315
+ link_field = "#{ type.short_name.downcase }_id".intern if link_field == nil
302
316
  super model, name, type, id_field, owned, back_field
303
317
  @table_name = table_name
304
318
  @link_field = link_field
@@ -327,7 +341,8 @@ class Model
327
341
 
328
342
  end
329
343
 
330
- class OneToManyField < Model::ArrayField
344
+ # @private
345
+ class OneToManyField < ArrayField
331
346
 
332
347
  def kind
333
348
  :backs
@@ -335,7 +350,8 @@ class Model
335
350
 
336
351
  end
337
352
 
338
- class SpecialField < Model::Field
353
+ # @private
354
+ class SpecialField < Field
339
355
 
340
356
  def initialize model, name, type, &block
341
357
  raise ArgumentError, "Block is required!", caller[1..] unless block_given?
@@ -359,7 +375,8 @@ class Model
359
375
 
360
376
  end
361
377
 
362
- class IgnoreField < Model::SpecialField
378
+ # @private
379
+ class IgnoreField < SpecialField
363
380
 
364
381
  def initialize model, name
365
382
  super model, name, Object do
@@ -433,7 +450,15 @@ class Model
433
450
  result.freeze
434
451
  end
435
452
 
436
- private def field name, type: nil, id_field: nil, required: false, index: false, unique: false, primary_key: false
453
+ # Defines a new field
454
+ # @param [Symbol] name
455
+ # @param [Class] type
456
+ # @return [void]
457
+ # @!macro [attach] field
458
+ # @api public
459
+ # @!attribute [rw]
460
+ # @return [$2] the +$1+ field
461
+ def field name, type: nil, id_field: nil, required: false, index: false, unique: false, primary_key: false
437
462
  raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name
438
463
  raise TypeError, "Field type must be a Module!", caller unless Module === type
439
464
  raise TypeError, "Argument 'id_field' must be a Symbol!", caller unless Symbol === id_field || id_field == nil
@@ -446,9 +471,17 @@ class Model
446
471
  @fields[name].implement
447
472
  end
448
473
 
449
- private def links name, item_type: nil, ids_field: nil, owned: true, table_name: nil, back_field: nil, link_field: nil, index: false
474
+ # Defines a new many-to-many field
475
+ # @param [Symbol] name
476
+ # @param [Class] item_type
477
+ # @return [void]
478
+ # @!macro [attach] links
479
+ # @api public
480
+ # @!attribute [rw]
481
+ # @return [Array<$2>] the +$1+ field
482
+ def links name, item_type: nil, ids_field: nil, owned: true, table_name: nil, back_field: nil, link_field: nil, index: false
450
483
  raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name
451
- raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && Entity > item_type
484
+ raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && INat::Entity > item_type
452
485
  raise TypeError, "Argument 'ids_field' must be a Symbol!", caller unless Symbol === ids_field || ids_field == nil
453
486
  raise TypeError, "Argument 'table_name' must be a Symbol!", caller unless Symbol === table_name || table_name == nil
454
487
  raise TypeError, "Argument 'back_field' must be a Symbol!", caller unless Symbol === back_field || back_field == nil
@@ -460,9 +493,17 @@ class Model
460
493
  @fields[name].implement
461
494
  end
462
495
 
463
- private def backs name, item_type: nil, ids_field: nil, owned: true, back_field: nil
496
+ # Defines a new one-to-many field
497
+ # @param [Symbol] name
498
+ # @param [Class] item_type
499
+ # @return [void]
500
+ # @!macro [attach] backs
501
+ # @api public
502
+ # @!attribute [rw]
503
+ # @return [Array<$2>] the +$1+ field
504
+ def backs name, item_type: nil, ids_field: nil, owned: true, back_field: nil
464
505
  raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name
465
- raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && Entity > item_type
506
+ raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && INat::Entity > item_type
466
507
  raise TypeError, "Argument 'ids_field' must be a Symbol!", caller unless Symbol === ids_field || ids_field == nil
467
508
  raise TypeError, "Argument 'back_field' must be a Symbol!", caller unless Symbol === back_field || back_field == nil
468
509
  raise TypeError, "Argument 'owned' must be a Boolean!", caller unless Boolean === owned
@@ -471,7 +512,15 @@ class Model
471
512
  @fields[name].implement
472
513
  end
473
514
 
474
- private def block name, type: nil, &block
515
+ # Defines a new write-only field
516
+ # @param [Symbol] name
517
+ # @param [Class] type
518
+ # @return [void]
519
+ # @!macro [attach] block
520
+ # @api public
521
+ # @!attribute [w]
522
+ # @return [$2] the +$1+ field
523
+ def block name, type: nil, &block
475
524
  raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name
476
525
  raise TypeError, "Field type must be a Module!", caller unless Module === type
477
526
  raise ArgumentError, "Block is required!", caller unless block_given?
@@ -14,9 +14,14 @@ require_relative 'types/std'
14
14
  require_relative 'types/location'
15
15
  require_relative 'types/extras'
16
16
 
17
- class Query
17
+ class INat::Query
18
18
 
19
- include LogDSL
19
+ using INat::Types::Std
20
+
21
+ include INat
22
+ include INat::App
23
+ include INat::App::Logger::DSL
24
+ include INat::Data::Types
20
25
 
21
26
  private def parse_accuracy value
22
27
  case value
@@ -1077,17 +1082,17 @@ class Query
1077
1082
  if mode != UpdateMode::MINIMAL
1078
1083
  actual_time = Time::new - Period::parse(G.config[:data][:update_period])
1079
1084
  end
1080
- actuals = Request::from_db_rows(DB.execute("SELECT * FROM requests WHERE time >= ?", actual_time.to_db)).select { |rq| self.in?(rq.query) }
1085
+ actuals = Entity::Request::from_db_rows(DB.execute("SELECT * FROM requests WHERE time >= ?", actual_time.to_db)).select { |rq| self.in?(rq.query) }
1081
1086
  end
1082
1087
  if actuals.empty? || mode == UpdateMode::FORCE
1083
1088
  # 2. Ищем чего бы обновить
1084
- request = Request::from_db_rows(DB.execute("SELECT * FROM requests WHERE query = ?", api_query)).first
1089
+ request = Entity::Request::from_db_rows(DB.execute("SELECT * FROM requests WHERE query = ?", api_query)).first
1085
1090
  updated_since = nil
1086
1091
  if request == nil
1087
1092
  query_string = api_query
1088
1093
  project_id = @api_params[:project_id]
1089
1094
  project_id = nil unless Integer === project_id
1090
- request = Request::create query_string, project_id
1095
+ request = Entity::Request::create query_string, project_id
1091
1096
  request.save
1092
1097
  else
1093
1098
  updated_since = request.time if mode != UpdateMode::RELOAD
@@ -1104,7 +1109,7 @@ class Query
1104
1109
  tt = nil
1105
1110
  cc = 0
1106
1111
  current_time = Time::new
1107
- API::query(:observations, **params) do |json, total|
1112
+ INat::API::query(:observations, **params) do |json, total|
1108
1113
  tt ||= total
1109
1114
  cc += 1
1110
1115
  pc = cc * 100 / tt
@@ -1113,7 +1118,7 @@ class Query
1113
1118
  pe = Period::make seconds: te
1114
1119
  pt = Period::make seconds: (Time::new - current_time).to_i
1115
1120
  Status::status nil, "Query \##{ @int_key } : R\##{ request.id } : parsed #{ format("%d of %d : %3d%% : time %s remain %s", cc, tt, pc, pt.to_hs, pe.to_hs) }"
1116
- obs = Observation::parse json
1121
+ obs = Entity::Observation::parse json
1117
1122
  obs.save
1118
1123
  DB.execute "INSERT OR REPLACE INTO request_observations (request_id, observation_id) VALUES (?, ?);", request.id, obs.id
1119
1124
  end
@@ -1123,12 +1128,12 @@ class Query
1123
1128
  # TODO: разобраться с удалением устаревшего
1124
1129
  # NEED: разобраться с частичной загрузкой — большие проекты грузятся недопустимо долго
1125
1130
  # возможно, стоит запараллелить обработку
1126
- request = Request::read(request.id).first
1131
+ request = Entity::Request::read(request.id).first
1127
1132
  end
1128
1133
  end
1129
1134
  # TODO: разобраться, где тупня
1130
1135
  sql, sql_args = db_where
1131
- result = Observation::from_db_rows(DB.execute("SELECT * FROM observations o#{ sql.empty? && '' || ' WHERE ' }#{ sql };", *sql_args))
1136
+ result = Entity::Observation::from_db_rows(DB.execute("SELECT * FROM observations o#{ sql.empty? && '' || ' WHERE ' }#{ sql };", *sql_args))
1132
1137
  if !@r_match.empty?
1133
1138
  result = result.filter { |o| self.match?(o) }
1134
1139
  end
@@ -3,7 +3,10 @@
3
3
  require_relative 'listers'
4
4
  require_relative 'list'
5
5
 
6
- class DataSet
6
+ class INat::Report::DataSet
7
+
8
+ include INat
9
+ include INat::Report
7
10
 
8
11
  attr_reader :time
9
12
  attr_accessor :object # TODO: переделать select так, чтобы не было необходимости во внешнем присваивании
@@ -74,7 +77,8 @@ class DataSet
74
77
  alias :=== :include?
75
78
 
76
79
  def << observation
77
- raise TypeError, "Argument must be an Observation (#{ observation.inspect })!" unless Observation === observation
80
+ raise TypeError, "Argument must be an Observation (#{ observation.inspect })!" unless Entity::Observation === observation
81
+ # TODO: добавить массивы и прочее
78
82
  if !self.include?(observation)
79
83
  @observations << observation
80
84
  @by_id[observation.id] = observation
@@ -84,17 +88,17 @@ class DataSet
84
88
 
85
89
  def | other
86
90
  obj = @object == other.object ? @object : nil
87
- DataSet::new obj, @observations + other.observations, time: Time::new
91
+ INat::Report::DataSet::new obj, @observations + other.observations, time: Time::new
88
92
  end
89
93
 
90
94
  def & other
91
95
  obj = @object == other.object ? @object : nil
92
- DataSet::new obj, @observations.select { |o| other.include?(o) }, time: Time::new
96
+ INat::Report::DataSet::new obj, @observations.select { |o| other.include?(o) }, time: Time::new
93
97
  end
94
98
 
95
99
  def - other
96
100
  obj = @object == other.object ? @object : nil
97
- DataSet::new obj, @observations.select { |o| !other.include?(o) }, time: Time::new
101
+ INat::Report::DataSet::new obj, @observations.select { |o| !other.include?(o) }, time: Time::new
98
102
  end
99
103
 
100
104
  def to_a
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- autoload :DataSet, 'inat/data/sets/dataset'
3
+ module INat::Report
4
+ autoload :DataSet, 'inat/data/sets/dataset'
5
+ end
6
+
7
+ class INat::Report::List
4
8
 
5
- class List
9
+ include INat
10
+ include INat::Report
6
11
 
7
12
  attr_reader :lister, :sorter
8
13
 
@@ -77,7 +82,7 @@ class List
77
82
 
78
83
  def << some
79
84
  case some
80
- when Observation
85
+ when Entity::Observation
81
86
  key = @lister.call some
82
87
  if key != nil
83
88
  @data[key] ||= DataSet::new key, [], time: @time
@@ -2,15 +2,20 @@
2
2
 
3
3
  require_relative 'wrappers'
4
4
 
5
- module Listers
5
+ # TODO: возможно, загнать внутрь List?
6
+
7
+ module INat::Report::Listers
8
+
9
+ include INat::Report
10
+ include INat::Data::Types
6
11
 
7
12
  SPECIES = lambda { |o| o.normalized_taxon(Rank::COMPLEX .. Rank::HYBRID) }
8
13
  GENUS = lambda { |o| o.normalized_taxon(Rank::GENUS) }
9
14
  FAMILY = lambda { |o| o.normalized_taxon(Rank::FAMILY) }
10
- YEAR = lambda { |o| Year[o.observed_on] }
11
- MONTH = lambda { |o| Month[o.observed_on] }
12
- DAY = lambda { |o| Day[o.observed_on] }
13
- WINTER = lambda { |o| Winter[o.observed_on] }
15
+ YEAR = lambda { |o| Period::Year[o.observed_on] }
16
+ MONTH = lambda { |o| Period::Month[o.observed_on] }
17
+ DAY = lambda { |o| Period::Day[o.observed_on] }
18
+ WINTER = lambda { |o| Period::Winter[o.observed_on] }
14
19
  USER = lambda { |o| o.user }
15
20
 
16
21
  end
@@ -2,7 +2,11 @@
2
2
 
3
3
  require 'date'
4
4
 
5
- class Calendarian
5
+ module INat::Report; end
6
+
7
+ # TODO: переделать в модуль namespace и Base-класс отдельно
8
+
9
+ class INat::Report::Period
6
10
 
7
11
  class << self
8
12
 
@@ -45,118 +49,118 @@ class Calendarian
45
49
  @value <=> other.value
46
50
  end
47
51
 
48
- end
52
+ class Year < INat::Report::Period
49
53
 
50
- class Year < Calendarian
54
+ class << self
51
55
 
52
- class << self
56
+ protected def date_to_value date
57
+ date.year
58
+ end
53
59
 
54
- protected def date_to_value date
55
- date.year
56
60
  end
57
61
 
58
- end
62
+ alias :year :value
59
63
 
60
- alias :year :value
64
+ def - num
65
+ self.class[@value - num]
66
+ end
61
67
 
62
- def - num
63
- self.class[@value - num]
64
- end
68
+ def to_s
69
+ "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ @value } год"
70
+ end
65
71
 
66
- def to_s
67
- "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ @value } год"
68
- end
72
+ def query_params
73
+ "year=#{ @value }"
74
+ end
69
75
 
70
- def query_params
71
- "year=#{ @value }"
72
76
  end
73
77
 
74
- end
78
+ class Month < INat::Report::Period
75
79
 
76
- class Month < Calendarian
80
+ class << self
77
81
 
78
- class << self
82
+ protected def date_to_value date
83
+ date.month
84
+ end
79
85
 
80
- protected def date_to_value date
81
- date.month
82
86
  end
83
87
 
84
- end
88
+ alias :month :value
89
+
90
+ NAMES = {
91
+ 1 => 'Январь',
92
+ 2 => 'Февраль',
93
+ 3 => 'Март',
94
+ 4 => 'Апрель',
95
+ 5 => 'Май',
96
+ 6 => 'Июнь',
97
+ 7 => 'Июль',
98
+ 8 => 'Август',
99
+ 9 => 'Сентябрь',
100
+ 10 => 'Октябрь',
101
+ 11 => 'Ноябрь',
102
+ 12 => 'Декабрь'
103
+ }
104
+
105
+ def to_s
106
+ "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ NAMES[@value] }"
107
+ end
85
108
 
86
- alias :month :value
87
-
88
- NAMES = {
89
- 1 => 'Январь',
90
- 2 => 'Февраль',
91
- 3 => 'Март',
92
- 4 => 'Апрель',
93
- 5 => 'Май',
94
- 6 => 'Июнь',
95
- 7 => 'Июль',
96
- 8 => 'Август',
97
- 9 => 'Сентябрь',
98
- 10 => 'Октябрь',
99
- 11 => 'Ноябрь',
100
- 12 => 'Декабрь'
101
- }
102
-
103
- def to_s
104
- "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ NAMES[@value] }"
105
- end
109
+ def query_params
110
+ "month=#{ @value }"
111
+ end
106
112
 
107
- def query_params
108
- "month=#{ @value }"
109
113
  end
110
114
 
111
- end
115
+ class Day < INat::Report::Period
112
116
 
113
- class Day < Calendarian
117
+ class << self
114
118
 
115
- class << self
119
+ protected def date_to_value date
120
+ date.day
121
+ end
116
122
 
117
- protected def date_to_value date
118
- date.day
119
123
  end
120
124
 
121
- end
125
+ alias :day :value
122
126
 
123
- alias :day :value
127
+ def to_s
128
+ "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ @value }"
129
+ end
124
130
 
125
- def to_s
126
- "<i class=\"glyphicon glyphicon-calendar\"></i>  #{ @value }"
127
- end
131
+ def query_params
132
+ "day=#{ @value }"
133
+ end
128
134
 
129
- def query_params
130
- "day=#{ @value }"
131
135
  end
132
136
 
133
- end
134
-
135
- class Winter < Calendarian
137
+ class Winter < INat::Report::Period
136
138
 
137
- class << self
139
+ class << self
138
140
 
139
- protected def date_to_value date
140
- month = date.month
141
- if month <= 4
142
- date.year
143
- elsif month >= 10
144
- date.year + 1
145
- else
146
- nil
141
+ protected def date_to_value date
142
+ month = date.month
143
+ if month <= 4
144
+ date.year
145
+ elsif month >= 10
146
+ date.year + 1
147
+ else
148
+ nil
149
+ end
147
150
  end
151
+
148
152
  end
149
153
 
150
- end
154
+ alias :winter :value
151
155
 
152
- alias :winter :value
156
+ def to_s
157
+ "<i class=\"glyphicon glyphicon-calendar\"></i>  Зима #{ @value - 1 }–#{ @value }"
158
+ end
153
159
 
154
- def to_s
155
- "<i class=\"glyphicon glyphicon-calendar\"></i>  Зима #{ @value - 1 }–#{ @value }"
156
- end
160
+ def query_params
161
+ "d1=#{ @value - 1 }-10-01&d2=#{ @value }-04-30"
162
+ end
157
163
 
158
- def query_params
159
- "d1=#{ @value - 1 }-10-01&d2=#{ @value }-04-30"
160
164
  end
161
165
 
162
166
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Location
3
+ module INat::Data; end
4
+ module INat::Data::Types; end
5
+
6
+ class INat::Data::Types::Location
4
7
 
5
8
  class << self
6
9
 
@@ -53,7 +56,7 @@ class Location
53
56
 
54
57
  end
55
58
 
56
- class Radius
59
+ class INat::Data::Types::Radius
57
60
 
58
61
  attr_reader :latitude, :longitude, :radius
59
62
 
@@ -66,7 +69,7 @@ class Radius
66
69
 
67
70
  end
68
71
 
69
- class Sector
72
+ class INat::Data::Types::Sector
70
73
 
71
74
  attr_reader :north, :east, :south, :west
72
75
 
@@ -80,10 +83,16 @@ class Sector
80
83
 
81
84
  end
82
85
 
83
- def radius latitude, longitude, radius
84
- Radius::new latitude, longitude, radius
85
- end
86
+ module INat::Data::Types
87
+
88
+ def radius latitude, longitude, radius
89
+ Radius::new latitude, longitude, radius
90
+ end
91
+
92
+ def sector north, east, south, west
93
+ Sector::new north, east, south, west
94
+ end
95
+
96
+ module_function :radius, :sector
86
97
 
87
- def sector north, east, south, west
88
- Sector::new north, east, south, west
89
98
  end