inat-get 0.9.0.18 → 0.9.2.4
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 +4 -4
- data/lib/inat-get/app/application.rb +7 -1
- data/lib/inat-get/app/core/api.rb +5 -1
- data/lib/inat-get/app/core/task.rb +16 -1
- data/lib/inat-get/app/setup.rb +17 -5
- data/lib/inat-get/data/dsl/dataset.rb +1 -1
- data/lib/inat-get/data/dsl/reports/base.rb +60 -0
- data/lib/inat-get/data/dsl/reports/erb.rb +42 -0
- data/lib/inat-get/data/dsl/reports.rb +3 -0
- data/lib/inat-get/data/parsers/defs/fromtaxon.rb +2 -2
- data/lib/inat-get/data/parsers/defs.rb +2 -1
- data/lib/inat-get/info.rb +3 -3
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 487c7043dbfd21d4d899bc1caf56dba18247b3d75564d96b7ef4dc3d8b797b53
|
|
4
|
+
data.tar.gz: 98de0f57594b65c2a7cd4d965221a0df4ef8052368cdd0e1d9c396db4d641fdc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9719c87ce41e33bf89bb0798ce030400c51fc9f8e7c37c5106ef091df8e3224dc3e61cb22a7875c7983f13a0559ed0daaf4b0b970970e2ea43706c90edf4698d
|
|
7
|
+
data.tar.gz: c2020ceb08590396257cead8a80c32f7255f8677b35dbedc6d57dbc813e88113ae5687ec4bae455e2aeb38a77454c594252c08b1f030cd9d25ae16a8428d97e6
|
|
@@ -34,7 +34,13 @@ class INatGet::App::Main
|
|
|
34
34
|
api = nil
|
|
35
35
|
api = INatGet::App::Server::API::create api_socket, console: console if !@config[:offline]
|
|
36
36
|
|
|
37
|
-
tasks = @config[:tasks].map
|
|
37
|
+
tasks = @config[:tasks].map do |path|
|
|
38
|
+
if path.end_with?('.erb')
|
|
39
|
+
INatGet::App::Task::ERB::new path, @config, console: console, api: api
|
|
40
|
+
else
|
|
41
|
+
INatGet::App::Task::new path, @config, console: console, api: api
|
|
42
|
+
end
|
|
43
|
+
end
|
|
38
44
|
Process::warmup
|
|
39
45
|
INatGet::App::Worker::enqueue @config, *tasks, console: console, api: api
|
|
40
46
|
console.quit
|
|
@@ -9,7 +9,7 @@ require 'is-duration'
|
|
|
9
9
|
|
|
10
10
|
require_relative 'server'
|
|
11
11
|
require_relative 'console_logger'
|
|
12
|
-
require_relative 'api_cache'
|
|
12
|
+
# require_relative 'api_cache'
|
|
13
13
|
|
|
14
14
|
class INatGet::App::Server::API < INatGet::App::Server
|
|
15
15
|
|
|
@@ -57,6 +57,10 @@ class INatGet::App::Server::API < INatGet::App::Server
|
|
|
57
57
|
|
|
58
58
|
def faraday
|
|
59
59
|
@faraday ||= Faraday::new do |f|
|
|
60
|
+
if (proxy_url = @config.dig(:api, :proxy))
|
|
61
|
+
f.proxy = proxy_url
|
|
62
|
+
end
|
|
63
|
+
|
|
60
64
|
f.request :retry,
|
|
61
65
|
max: @config.dig(:api, :retry, :max),
|
|
62
66
|
interval: IS::Duration::parse(@config.dig(:api, :retry, :interval)),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'erb'
|
|
4
|
+
|
|
3
5
|
require 'sequel'
|
|
4
6
|
Sequel.extension :core_extensions
|
|
5
7
|
Sequel.datetime_class = Time
|
|
@@ -8,6 +10,7 @@ Sequel.application_timezone = :local
|
|
|
8
10
|
|
|
9
11
|
require_relative '../../info'
|
|
10
12
|
require_relative '../../data/dsl/dsl'
|
|
13
|
+
require_relative '../../data/dsl/reports'
|
|
11
14
|
require_relative 'console_logger'
|
|
12
15
|
|
|
13
16
|
class INatGet::App::Task
|
|
@@ -67,7 +70,7 @@ class INatGet::App::Task
|
|
|
67
70
|
Sequel::Model.strict_param_setting = false
|
|
68
71
|
Sequel::Model.raise_on_save_failure = true
|
|
69
72
|
Sequel::Model.db = @db
|
|
70
|
-
|
|
73
|
+
Sequel::Model.db.loggers << ::Logger::new("sequel.log", level: :info)
|
|
71
74
|
require_relative '../../data/models'
|
|
72
75
|
require_relative '../../data/managers'
|
|
73
76
|
# # ... etc
|
|
@@ -80,3 +83,15 @@ class INatGet::App::Task
|
|
|
80
83
|
end
|
|
81
84
|
|
|
82
85
|
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class INatGet::App::Task::ERB < INatGet::App::Task
|
|
89
|
+
|
|
90
|
+
TRIM_MODE = ''
|
|
91
|
+
|
|
92
|
+
def execute
|
|
93
|
+
report = INatGet::Data::DSL::Report::ERB::new file: @path, trim_mode: TRIM_MODE
|
|
94
|
+
report.save
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
data/lib/inat-get/app/setup.rb
CHANGED
|
@@ -36,11 +36,11 @@ module INatGet::App::Setup
|
|
|
36
36
|
caching: {
|
|
37
37
|
api: 100,
|
|
38
38
|
update: '4h',
|
|
39
|
-
refresh: {
|
|
39
|
+
refresh: {
|
|
40
40
|
interval: '4d',
|
|
41
41
|
depth: '40d'
|
|
42
42
|
},
|
|
43
|
-
recache: {
|
|
43
|
+
recache: {
|
|
44
44
|
count: 200,
|
|
45
45
|
method: 'oldest' # oldest by cached, newest by updated, sample — random
|
|
46
46
|
},
|
|
@@ -160,6 +160,11 @@ module INatGet::App::Setup
|
|
|
160
160
|
options[:config] = value
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
+
o.on '-p', '--proxy URI', String, 'Use proxy by URI.' do |value|
|
|
164
|
+
options[:api] ||= {}
|
|
165
|
+
options[:proxy] ||= value
|
|
166
|
+
end
|
|
167
|
+
|
|
163
168
|
o.on '-l', '--log-level LEVEL', [ 'fatal', 'error', 'warn', 'info', 'debug' ], 'Log level (fatal, error, warn, info or debug).' do |value|
|
|
164
169
|
options[:logs] ||= {}
|
|
165
170
|
options[:logs][:screen] ||= {}
|
|
@@ -192,7 +197,7 @@ module INatGet::App::Setup
|
|
|
192
197
|
options[:logs][:file][:wrk] = 'debug'
|
|
193
198
|
end
|
|
194
199
|
|
|
195
|
-
o.on '-o', '--offline', 'Offline mode: no updates, use local database only.' do
|
|
200
|
+
o.on '-o', '--offline', 'Offline mode: no updates, use local database only.' do
|
|
196
201
|
options[:offline] = true
|
|
197
202
|
end
|
|
198
203
|
|
|
@@ -267,7 +272,7 @@ module INatGet::App::Setup
|
|
|
267
272
|
if File.exist?(list_file)
|
|
268
273
|
unwrap_file_list File.readlines(list_file, chomp: true)
|
|
269
274
|
else
|
|
270
|
-
$stderr.puts "❌ \e[1mList file not found:\e[0m #{ list_file }\e[1m. Stopped!\e[0m"
|
|
275
|
+
$stderr.puts "❌ \e[1mList file not found:\e[0m #{ list_file }\e[1m. Stopped!\e[0m"
|
|
271
276
|
exit Errno::ENOENT::Errno
|
|
272
277
|
end
|
|
273
278
|
else
|
|
@@ -277,6 +282,14 @@ module INatGet::App::Setup
|
|
|
277
282
|
"#{ file }.inat"
|
|
278
283
|
elsif File.exist?("#{ file }.rb")
|
|
279
284
|
"#{ file }.rb"
|
|
285
|
+
elsif File.exist?("#{ file }.erb")
|
|
286
|
+
"#{ file }.erb"
|
|
287
|
+
elsif File.exist?("#{ file }.md.erb")
|
|
288
|
+
"#{ file }.md.erb"
|
|
289
|
+
elsif File.exist?("#{ file }.html.erb")
|
|
290
|
+
"#{ file }.html.erb"
|
|
291
|
+
elsif File.exist?("#{ file }.htm.erb")
|
|
292
|
+
"#{ file }.htm.erb"
|
|
280
293
|
else
|
|
281
294
|
$stderr.puts "❌ \e[1mTask file not found:\e[0m #{ file }\e[1m. Stopped!\e[0m"
|
|
282
295
|
exit Errno::ENOENT::Errno
|
|
@@ -288,4 +301,3 @@ module INatGet::App::Setup
|
|
|
288
301
|
end
|
|
289
302
|
|
|
290
303
|
end
|
|
291
|
-
|
|
@@ -213,7 +213,7 @@ class INatGet::Data::DSL::Dataset
|
|
|
213
213
|
|
|
214
214
|
case reflection[:type]
|
|
215
215
|
when :many_to_one
|
|
216
|
-
ids = query.distinct.select_map(reflection[:key])
|
|
216
|
+
ids = query.select(reflection[:key]).distinct.select_map(reflection[:key])
|
|
217
217
|
target.where(id: ids)
|
|
218
218
|
when :one_to_many, :many_to_many
|
|
219
219
|
# Для всех типов "много" используем ассоциативный датасет
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../info.rb'
|
|
4
|
+
require_relative '../dsl'
|
|
5
|
+
|
|
6
|
+
class INatGet::Data::DSL::Report
|
|
7
|
+
|
|
8
|
+
include INatGet::Data::DSL
|
|
9
|
+
|
|
10
|
+
def initialize mode: nil, suffix: nil, **data
|
|
11
|
+
@mode = mode
|
|
12
|
+
@data = data
|
|
13
|
+
@suffix = suffix
|
|
14
|
+
yield self if block_given?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [String]
|
|
18
|
+
def basename suffix = nil
|
|
19
|
+
suffix ||= @suffix
|
|
20
|
+
if suffix
|
|
21
|
+
self.name + ' -- ' + suffix
|
|
22
|
+
else
|
|
23
|
+
self.name
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [String]
|
|
28
|
+
def ext mode: nil
|
|
29
|
+
(mode || @mode)&.to_s
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [String]
|
|
33
|
+
def filename suffix: nil, mode: nil
|
|
34
|
+
if self.ext(mode: mode)
|
|
35
|
+
self.basename(suffix) + '.' + self.ext(mode: mode)
|
|
36
|
+
else
|
|
37
|
+
self.basename(suffix)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [String]
|
|
42
|
+
def render mode: nil
|
|
43
|
+
raise NotImplementedError, "Not implemented method 'render' for abstract Report", caller_locations
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [void]
|
|
47
|
+
def save filename = nil, suffix: nil, mode: nil
|
|
48
|
+
filename ||= self.filename(suffix: suffix, mode: mode)
|
|
49
|
+
File.write filename, self.render(mode: mode)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def [] key
|
|
53
|
+
@data[key]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def []= key, value
|
|
57
|
+
@data[key] = value
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'erb'
|
|
4
|
+
|
|
5
|
+
require_relative 'base'
|
|
6
|
+
|
|
7
|
+
class INatGet::Data::DSL::Report::ERB < INatGet::Data::DSL::Report
|
|
8
|
+
|
|
9
|
+
def initialize code = nil, file: nil, ext: nil, trim_mode: nil, suffix: nil, **data, &block
|
|
10
|
+
@code = code
|
|
11
|
+
@code ||= File.read(file) if file
|
|
12
|
+
raise ArgumentError, "Source not specified", caller_locations unless @code
|
|
13
|
+
@ext = ext
|
|
14
|
+
@ext ||= File.extname(File.basename(file, '.erb')) if file
|
|
15
|
+
@erb = ::ERB::new @code, trim_mode: trim_mode
|
|
16
|
+
@erb.filename = file || '(erb)'
|
|
17
|
+
suffix ||= File.basename(File.basename(file, '.erb'), '.*') if file
|
|
18
|
+
super(mode: nil, suffix: suffix, **data, &block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Hash]
|
|
22
|
+
attr_reader :data
|
|
23
|
+
|
|
24
|
+
# @return [String]
|
|
25
|
+
def ext mode: nil
|
|
26
|
+
@ext
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [String]
|
|
30
|
+
def render
|
|
31
|
+
@erb.result binding
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module INatGet::Data::DSL
|
|
37
|
+
|
|
38
|
+
def erb_report code = nil, file: nil, ext: nil, trim_mode: nil, suffix: nil, **data, &block
|
|
39
|
+
INatGet::Data::DSL::Report::ERB::new(code, file: file, ext: ext, trim_mode: trim_mode, suffix: suffix, **data, &block)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -105,7 +105,8 @@ class INatGet::Data::Parser
|
|
|
105
105
|
end
|
|
106
106
|
associations, attributes = rest.partition { |p| p.is_a?(Part::Assoc) }
|
|
107
107
|
attributes.each do |a|
|
|
108
|
-
|
|
108
|
+
res = a.parse source
|
|
109
|
+
fields.merge! res if res
|
|
109
110
|
end
|
|
110
111
|
record = nil
|
|
111
112
|
model.db.transaction(isolation: :committed, mode: :immediate) do
|
data/lib/inat-get/info.rb
CHANGED
|
@@ -5,8 +5,8 @@ module INatGet; end
|
|
|
5
5
|
module INatGet::Info
|
|
6
6
|
|
|
7
7
|
NAME = 'inat-get'
|
|
8
|
-
VERSION = '0.9.
|
|
9
|
-
VERSION_ALIAS = '
|
|
8
|
+
VERSION = '0.9.2.4'
|
|
9
|
+
VERSION_ALIAS = 'Parus major'
|
|
10
10
|
|
|
11
11
|
AUTHOR = 'Ivan Shikhalev'
|
|
12
12
|
AUTHOR_URL = 'https://github.com/shikhalev'
|
|
@@ -19,5 +19,5 @@ module INatGet::Info
|
|
|
19
19
|
DESCRIPTION = 'iNaturalist API query builder and analytics tool'
|
|
20
20
|
|
|
21
21
|
HOMEPAGE = 'https://github.com/inat-get/inat-get'
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
end
|
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.
|
|
4
|
+
version: 0.9.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ivan Shikhalev
|
|
@@ -296,6 +296,9 @@ files:
|
|
|
296
296
|
- lib/inat-get/data/dsl/dataset.rb
|
|
297
297
|
- lib/inat-get/data/dsl/dsl.rb
|
|
298
298
|
- lib/inat-get/data/dsl/list.rb
|
|
299
|
+
- lib/inat-get/data/dsl/reports.rb
|
|
300
|
+
- lib/inat-get/data/dsl/reports/base.rb
|
|
301
|
+
- lib/inat-get/data/dsl/reports/erb.rb
|
|
299
302
|
- lib/inat-get/data/helpers/base.rb
|
|
300
303
|
- lib/inat-get/data/helpers/defs.rb
|
|
301
304
|
- lib/inat-get/data/helpers/defs/accuracy.rb
|