inat-get 0.9.0.12 → 0.9.0.14

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1728f650aec437e88f0d9ba844695b9ffd5d4e9410aa3fa72a7d2e855943b9d2
4
- data.tar.gz: 22b960c8392bd3b786e4d067877bd10cf7f11594fd240697e53def459403968c
3
+ metadata.gz: 05a4272992b33172ef754c61f1d1d1c89a11cc7efe51cb84420efda09bfff858
4
+ data.tar.gz: 702308f230e526f0a10125c2785b258a0417f513937f3111a816e0f727734262
5
5
  SHA512:
6
- metadata.gz: edf53795eacbf7606eec2172e5129143530c7bb5f3aee34386fb37eda9fdce7472df15d8d01579542ae7b31edaf7d9b5aa3e47f4affd4a6b8c18c22b56d09949
7
- data.tar.gz: 5bba1a958b59ae606cdce9a8c1914f0c9a85c29f5f440e673387f868278df17012f48d6fea4c0e653d7bd40ef986c9cc86dfd70a8c2a0cbaf5d20f30f359bef3
6
+ metadata.gz: 673c18491a5152a65e5d6773f325125fa98824ee8ac6dc543e0d57cd50dafa9cac0751ab4ad522de7ecd9eaa9f87b77e2af56d8b64323c74ee83507aa43c76b4
7
+ data.tar.gz: a6c4facdb3f9ba680f693e58c9bf788ddf71ae0b0b675d457dc1b6b4ab82ee67dfa50a22a327fc81fad1e8b51710faea27f3b2a145eda9fda2eb8e1532fa5b22
@@ -2,10 +2,14 @@
2
2
 
3
3
  require 'faraday'
4
4
  require 'faraday/retry'
5
+ require 'faraday/typhoeus'
6
+ # require 'faraday/gzip'
7
+ # require 'faraday-http-cache'
5
8
  require 'is-duration'
6
9
 
7
10
  require_relative 'server'
8
11
  require_relative 'console_logger'
12
+ require_relative 'api_cache'
9
13
 
10
14
  class INatGet::App::Server::API < INatGet::App::Server
11
15
 
@@ -21,6 +25,7 @@ class INatGet::App::Server::API < INatGet::App::Server
21
25
 
22
26
  def get query, **opts
23
27
  endpoint = @config.dig(:api, :root) + query[:endpoint].to_s
28
+ @logger.info query[:endpoint].to_s
24
29
  timepoint = Time::now
25
30
  if @last_request
26
31
  delta = timepoint - @last_request
@@ -33,6 +38,7 @@ class INatGet::App::Server::API < INatGet::App::Server
33
38
  rq.params.merge! query[:query]
34
39
  rq.headers["User-Agent"] = "iNatGet v#{INatGet::Info::VERSION} (#{ INatGet::Info::VERSION_ALIAS })"
35
40
  end
41
+ @logger.clear
36
42
  if response.success?
37
43
  begin
38
44
  data = JSON.parse response.body, symbolize_names: true
@@ -45,6 +51,8 @@ class INatGet::App::Server::API < INatGet::App::Server
45
51
  @logger.error "Error in response: #{response.status}"
46
52
  return { status: :error, error: response.status }.freeze
47
53
  end
54
+ # rescue => e
55
+ # return { status: :error, error: e.message }.freeze
48
56
  end
49
57
 
50
58
  def faraday
@@ -55,10 +63,19 @@ class INatGet::App::Server::API < INatGet::App::Server
55
63
  interval: IS::Duration::parse(@config.dig(:api, :retry, :interval)),
56
64
  interval_randomness: @config.dig(:api, :retry, :randomness),
57
65
  backoff_factor: @config.dig(:api, :retry, :backoff),
66
+ retry_block: lambda { |env:, options:, retry_count:, exception:, will_retry_in:| @logger.warn "retry... : #{ retry_count } : #{ exception.class }" },
58
67
  exceptions: [Faraday::TimeoutError, Faraday::ConnectionFailed, Faraday::SSLError, Faraday::ClientError]
59
68
  f.request :url_encoded
60
- # f.response :logger, tmp_logger, bodies: true, headers: true
61
- f.adapter Faraday::default_adapter
69
+ # f.response :logger, tmp_logger, { headers: true, bodies: false }
70
+
71
+ # f.use :http_cache, store: INatGet::App::Server::API::Cache::new(@config.dig(:caching, :api) || 100)
72
+
73
+ f.adapter :typhoeus do |typhoeus|
74
+ typhoeus.options[:connecttimeout] = 10
75
+ typhoeus.options[:timeout] = 20
76
+ typhoeus.options[:low_speed_limit] = 10
77
+ typhoeus.options[:low_speed_time] = 10
78
+ end
62
79
  end
63
80
  end
64
81
 
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../info'
4
+
5
+ module INatGet::App
6
+ class Server
7
+ class API < INatGet::App::Server; end
8
+ end
9
+ end
10
+
11
+ # @api private
12
+ class INatGet::App::Server::API::Cache
13
+
14
+ def initialize limit = 100
15
+ @limit = limit
16
+ @data = {}
17
+ end
18
+
19
+ def read key
20
+ return nil unless @data.has_key?(key)
21
+ value = @data.delete key
22
+ @data[key] = value
23
+ value
24
+ end
25
+
26
+ def write key, value
27
+ @data.delete key
28
+ @data[key] = value
29
+ @data.shift if @data.size > @limit
30
+ value
31
+ end
32
+
33
+ def delete key
34
+ @data.delete key
35
+ end
36
+
37
+ end
@@ -65,6 +65,16 @@ class INatGet::App::Server::Console < INatGet::App::Server
65
65
  true
66
66
  end
67
67
 
68
+ def clear progname, **opts
69
+ key = prog_key progname
70
+ pid = opts[:_sender_pid]
71
+ if key == :wrk
72
+ @table.update _sender_pid: pid, message: ''
73
+ else
74
+ @table.summary message: ''
75
+ end
76
+ end
77
+
68
78
  private
69
79
 
70
80
  def prog_key progname
@@ -24,4 +24,8 @@ class INatGet::App::ConsoleLogger < Logger
24
24
  @console.log severity, msg, (progname || self.progname)
25
25
  end
26
26
 
27
+ def clear progname = nil
28
+ @console.clear(progname || self.progname)
29
+ end
30
+
27
31
  end
@@ -66,6 +66,7 @@ class INatGet::App::Server
66
66
  end
67
67
 
68
68
  def on_error exception
69
+ warn exception.class
69
70
  warn exception
70
71
  warn exception.backtrace
71
72
  end
@@ -92,7 +93,7 @@ class INatGet::App::Server
92
93
  end
93
94
 
94
95
  def method_missing sym, *args, **kwargs
95
- kwargs[:_sender_pid] = ::Process::pid
96
+ kwargs[:_sender_pid] ||= ::Process::pid
96
97
  msg = {
97
98
  method: sym,
98
99
  args: args,
@@ -104,8 +105,8 @@ class INatGet::App::Server
104
105
  socket.close
105
106
  result
106
107
  rescue => e
107
- pp e
108
- false
108
+ # pp e
109
+ { status: :error, error: e.message }
109
110
  end
110
111
 
111
112
  end
@@ -16,8 +16,8 @@ module INatGet::App::Setup
16
16
  DEFAULTS = {
17
17
  logs: {
18
18
  screen: {
19
- api: 'warn',
20
- sys: 'warn',
19
+ api: 'info',
20
+ sys: 'info',
21
21
  wrk: 'info'
22
22
  },
23
23
  file: {
@@ -34,6 +34,7 @@ module INatGet::App::Setup
34
34
  password: nil
35
35
  },
36
36
  caching: {
37
+ api: 100,
37
38
  update: '4h',
38
39
  refresh: {
39
40
  interval: '4d',
@@ -62,7 +63,7 @@ module INatGet::App::Setup
62
63
  preferred_place: 7161,
63
64
  translate_projects: 'umbrella', # all | umbrella | none
64
65
  retry: {
65
- max: 5,
66
+ max: 25,
66
67
  interval: '1s',
67
68
  randomness: 0.5,
68
69
  backoff: 2
@@ -52,6 +52,19 @@ module INatGet::Data
52
52
 
53
53
  end
54
54
 
55
+ module Identified
56
+
57
+ def eql? other
58
+ return false unless other.is_a?(self.class)
59
+ self.id == other.id
60
+ end
61
+
62
+ def hash
63
+ [Identified, self.class, self.id].hash
64
+ end
65
+
66
+ end
67
+
55
68
  end
56
69
 
57
70
  end
@@ -10,6 +10,8 @@ module INatGet::Data; end
10
10
 
11
11
  class INatGet::Data::Model::Identification < INatGet::Data::Model
12
12
 
13
+ include INatGet::Data::Model::Identified
14
+
13
15
  set_dataset :identifications
14
16
 
15
17
  many_to_one :observation, class: :'INatGet::Data::Model::Observation'
@@ -18,6 +18,8 @@ module INatGet::Data; end
18
18
 
19
19
  class INatGet::Data::Model::Observation < INatGet::Data::Model
20
20
 
21
+ include INatGet::Data::Model::Identified
22
+
21
23
  set_dataset :observations
22
24
 
23
25
  one_to_many :faves, class: INatGet::Data::Model::Fave
@@ -9,6 +9,8 @@ module INatGet::Data; end
9
9
 
10
10
  class INatGet::Data::Model::Photo < INatGet::Data::Model
11
11
 
12
+ include INatGet::Data::Model::Identified
13
+
12
14
  set_dataset :photos
13
15
 
14
16
  many_to_many :observations, class: :'INatGet::Data::Model::Observation', join_table: :observation_photos, left_key: :photo_id, right_key: :observation_id
@@ -9,6 +9,8 @@ module INatGet::Data; end
9
9
 
10
10
  class INatGet::Data::Model::Place < INatGet::Data::Model
11
11
 
12
+ include INatGet::Data::Model::Identified
13
+
12
14
  set_dataset :places
13
15
 
14
16
  many_to_many :observations, class: :'INatGet::Data::Model::Observation', join_table: :observation_places, left_key: :place_id, right_key: :observation_id
@@ -16,6 +16,8 @@ module INatGet::Data; end
16
16
 
17
17
  class INatGet::Data::Model::Project < INatGet::Data::Model
18
18
 
19
+ include INatGet::Data::Model::Identified
20
+
19
21
  set_dataset :projects
20
22
 
21
23
  many_to_one :user, class: :'INatGet::Data::Model::User'
@@ -6,6 +6,8 @@ require_relative "../../info"
6
6
 
7
7
  class INatGet::Data::Model::Sound < INatGet::Data::Model
8
8
 
9
+ include INatGet::Data::Model::Identified
10
+
9
11
  set_dataset :sounds
10
12
 
11
13
  many_to_many :observations, class: :'INatGet::Data::Model::Observation', join_table: :observation_sounds, left_key: :sound_id, right_key: :observation_id
@@ -8,6 +8,8 @@ require_relative 'base'
8
8
 
9
9
  class INatGet::Data::Model::Taxon < INatGet::Data::Model
10
10
 
11
+ include INatGet::Data::Model::Identified
12
+
11
13
  set_dataset :taxa
12
14
 
13
15
  one_to_many :observations
@@ -7,6 +7,8 @@ require_relative 'base'
7
7
 
8
8
  class INatGet::Data::Model::User < INatGet::Data::Model
9
9
 
10
+ include INatGet::Data::Model::Identified
11
+
10
12
  set_dataset :users
11
13
 
12
14
  one_to_many :observations
@@ -146,25 +146,30 @@ class INatGet::Data::Updater
146
146
  rq_model = INatGet::Data::Model::Request
147
147
  record = nil
148
148
  found = false
149
- rq_model.db.transaction(isolation: :committed, mode: :immediate) do
149
+ # rq_model.db.transaction(isolation: :committed, mode: :immediate) do
150
150
  record = rq_model.with_pk(rq_hash)
151
151
  if record
152
152
  while record.busy
153
153
  raise "Too old business" if start_point - record.busy > HARD_STOP
154
+ console.update status: 'waiting...'
154
155
  sleep 0.1
155
156
  record.reload
156
157
  end
157
158
  return :fresh if record.finished > actual_point
158
- record.update busy: start_point
159
+ rq_model.db.transaction(isolation: :committed, mode: :immediate) do
160
+ record.update busy: start_point
161
+ end
159
162
  found = true
160
163
  else
161
- record = rq_model.create full: rq_hash, endless: el_hash, endpoint: endpoint.to_s, query: rq_json, started: start_point, freshed: start_point, busy: start_point
162
- set_request_projects record, query[:project_id] if query[:project_id]
163
- set_request_places record, query[:place_id] if query[:place_id]
164
- set_request_taxa record, query[:taxon_id] if query[:taxon_id]
165
- set_request_users record, query[:user_id] if query[:user_id]
164
+ rq_model.db.transaction(isolation: :committed, mode: :immediate) do
165
+ record = rq_model.create full: rq_hash, endless: el_hash, endpoint: endpoint.to_s, query: rq_json, started: start_point, freshed: start_point, busy: start_point
166
+ set_request_projects record, query[:project_id] if query[:project_id]
167
+ set_request_places record, query[:place_id] if query[:place_id]
168
+ set_request_taxa record, query[:taxon_id] if query[:taxon_id]
169
+ set_request_users record, query[:user_id] if query[:user_id]
170
+ end
166
171
  end
167
- end
172
+ # end
168
173
 
169
174
  # Устанавливаем updated_since
170
175
  if allow_updated_since?
@@ -307,6 +312,7 @@ class INatGet::Data::Updater
307
312
  until result
308
313
  query[:id_above] = id_above if id_above
309
314
  check_shutdown!
315
+ console.update status: 'querying...'
310
316
  response = api.get({ endpoint: endpoint, query: query })
311
317
  if response[:status] == :error
312
318
  result = :error
@@ -335,6 +341,7 @@ class INatGet::Data::Updater
335
341
  until result
336
342
  query[:page] = page if page
337
343
  check_shutdown!
344
+ console.update status: 'querying...'
338
345
  response = api.get({ endpoint: endpoint, query: query })
339
346
  if response[:status] == :error
340
347
  result = :error
data/lib/inat-get/info.rb CHANGED
@@ -5,7 +5,7 @@ module INatGet; end
5
5
  module INatGet::Info
6
6
 
7
7
  NAME = 'inat-get'
8
- VERSION = '0.9.0.12'
8
+ VERSION = '0.9.0.14'
9
9
  VERSION_ALIAS = 'Carduelis carduelis'
10
10
 
11
11
  AUTHOR = 'Ivan Shikhalev'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inat-get
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.12
4
+ version: 0.9.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Shikhalev
@@ -51,6 +51,34 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '2.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: faraday-http-cache
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.6'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.6'
68
+ - !ruby/object:Gem::Dependency
69
+ name: faraday-typhoeus
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.1'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.1'
54
82
  - !ruby/object:Gem::Dependency
55
83
  name: is-dsl
56
84
  requirement: !ruby/object:Gem::Requirement
@@ -71,14 +99,14 @@ dependencies:
71
99
  requirements:
72
100
  - - "~>"
73
101
  - !ruby/object:Gem::Version
74
- version: 0.8.8.6
102
+ version: 0.8.10
75
103
  type: :runtime
76
104
  prerelease: false
77
105
  version_requirements: !ruby/object:Gem::Requirement
78
106
  requirements:
79
107
  - - "~>"
80
108
  - !ruby/object:Gem::Version
81
- version: 0.8.8.6
109
+ version: 0.8.10
82
110
  - !ruby/object:Gem::Dependency
83
111
  name: is-duration
84
112
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +278,7 @@ files:
250
278
  - lib/inat-get/app.rb
251
279
  - lib/inat-get/app/application.rb
252
280
  - lib/inat-get/app/core/api.rb
281
+ - lib/inat-get/app/core/api_cache.rb
253
282
  - lib/inat-get/app/core/console.rb
254
283
  - lib/inat-get/app/core/console_logger.rb
255
284
  - lib/inat-get/app/core/server.rb