inat-get 0.8.0.12 → 0.8.0.13

Sign up to get free protection for your applications and to get access to all the features.
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