embulk-input-healthplanet 1.0.0
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 +7 -0
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +56 -0
- data/Rakefile +3 -0
- data/embulk-input-healthplanet.gemspec +24 -0
- data/lib/embulk/input/healthplanet.rb +245 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a6559e9ab461422fdb84aae86853330560023ae9
|
4
|
+
data.tar.gz: b67eb584c925f946fa95a2e038a2cf82dc389062
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f3f1233856605a544b0e10f74d26510c1f6b038f868fe0ca621a2716a41ffbaa6aeabb726fb54387e5f47c1e47007ad421361f81a559ac9e06a62bd0d59bdb3f
|
7
|
+
data.tar.gz: c1c046e24a1f549b2d7185bf999814b97924946f6110640e91db0e31369389ec5547ac27091f578270ccd400588fdc82750ece5a2930072b7bed24ae5c31ca5f
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
jruby-9.0.0.0
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
MIT License
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Healthplanet input plugin for Embulk
|
2
|
+
|
3
|
+
Retrieve your innerscan data through Health Planet API v1.
|
4
|
+
|
5
|
+
This plugin only supports 'innerscan' scope. Other scopes such as 'sphygmomanometer', 'pedometer' and 'smug' are not supported.
|
6
|
+
|
7
|
+
## Overview
|
8
|
+
|
9
|
+
* **Plugin type**: input
|
10
|
+
* **Resume supported**: no
|
11
|
+
* **Cleanup supported**: no
|
12
|
+
* **Guess supported**: no
|
13
|
+
|
14
|
+
## Install
|
15
|
+
|
16
|
+
```
|
17
|
+
$ embulk gem install embulk-input-healthplanet
|
18
|
+
```
|
19
|
+
|
20
|
+
## Configuration
|
21
|
+
|
22
|
+
- **login_id**: Login ID for Health Planet website (string, required)
|
23
|
+
- **password**: Password for Health Planet website (string, required)
|
24
|
+
- **client_id**: Client ID for your client application using this plugin (string, required)
|
25
|
+
- **client_secret**: Client Secret for your client application using this plugin (string, required)
|
26
|
+
- **next_from**: Retrieve data from the time '%Y-%m-%d %H:%M:%S' (string, default: 1 year ago)
|
27
|
+
|
28
|
+
## Example
|
29
|
+
|
30
|
+
```yaml
|
31
|
+
in:
|
32
|
+
type: healthplanet
|
33
|
+
login_id: example_login_id
|
34
|
+
password: example_password
|
35
|
+
client_id: example.apps.healthplanet.jp
|
36
|
+
client_secret: 12345678901123-ExampleClientSecret
|
37
|
+
next_from: '2015-01-01 00:00:00'
|
38
|
+
exec: {}
|
39
|
+
out:
|
40
|
+
type: file
|
41
|
+
path_prefix: ./healthplanet/
|
42
|
+
file_ext: csv
|
43
|
+
formatter:
|
44
|
+
type: csv
|
45
|
+
default_timezone: 'Asia/Tokyo'
|
46
|
+
```
|
47
|
+
|
48
|
+
If only new records are required, please use -o option as follows:
|
49
|
+
|
50
|
+
```
|
51
|
+
$ embulk run config.yml -o config.yml
|
52
|
+
```
|
53
|
+
|
54
|
+
## References
|
55
|
+
|
56
|
+
* [Health Planet API Specification Ver. 1.0 (Japanese)](http://www.healthplanet.jp/apis/api.html)
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "embulk-input-healthplanet"
|
4
|
+
spec.version = "1.0.0"
|
5
|
+
spec.authors = ["Masahiro Yoshizawa"]
|
6
|
+
spec.summary = "Healthplanet input plugin for Embulk"
|
7
|
+
spec.description = "Retrieve your innerscan data through Health Planet API v1."
|
8
|
+
spec.email = ["muziyoshiz@gmail.com"]
|
9
|
+
spec.licenses = ["MIT"]
|
10
|
+
spec.homepage = "https://github.com/muziyoshiz/embulk-input-healthplanet"
|
11
|
+
|
12
|
+
spec.files = `git ls-files`.split("\n") + Dir["classpath/*.jar"]
|
13
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
#spec.add_dependency 'YOUR_GEM_DEPENDENCY', ['~> YOUR_GEM_DEPENDENCY_VERSION']
|
17
|
+
spec.add_development_dependency 'embulk', ['~> 0.7.10']
|
18
|
+
spec.add_development_dependency 'bundler', ['~> 1.0']
|
19
|
+
spec.add_development_dependency 'rake', ['>= 10.0']
|
20
|
+
|
21
|
+
spec.add_dependency 'faraday', ['~> 0.8.11']
|
22
|
+
spec.add_dependency 'faraday-cookie_jar', ['~> 0.0.6']
|
23
|
+
spec.add_dependency 'oga', ['~> 2.0.0']
|
24
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday-cookie_jar'
|
3
|
+
require 'oga'
|
4
|
+
require 'nkf'
|
5
|
+
require 'json'
|
6
|
+
require 'time'
|
7
|
+
|
8
|
+
module Embulk
|
9
|
+
module Input
|
10
|
+
|
11
|
+
class Healthplanet < InputPlugin
|
12
|
+
Plugin.register_input("healthplanet", self)
|
13
|
+
|
14
|
+
# Default redirect URI for Client Application
|
15
|
+
REDIRECT_URI = 'https://www.healthplanet.jp/success.html'
|
16
|
+
|
17
|
+
# Default scope
|
18
|
+
DEFAULT_SCOPE = 'innerscan'
|
19
|
+
|
20
|
+
# Default response type
|
21
|
+
DEFAULT_RESPONSE_TYPE = 'code'
|
22
|
+
|
23
|
+
# Default grant type
|
24
|
+
DEFAULT_GRANT_TYPE = 'authorization_code'
|
25
|
+
|
26
|
+
# All tags for innerscan
|
27
|
+
ALL_TAGS = '6021,6022,6023,6024,6025,6026,6027,6028,6029'
|
28
|
+
|
29
|
+
# Health Planet API can response only in 3 months
|
30
|
+
RESPONSE_INTERVAL = 60*60*24*30*3
|
31
|
+
|
32
|
+
# embulk-input-healthplanet retrieves data from one year ago by default
|
33
|
+
# If you need data more than one year ago, please set 'next_from' parameter
|
34
|
+
DEFAULT_FROM_TIME = 60*60*24*365
|
35
|
+
|
36
|
+
def self.transaction(config, &control)
|
37
|
+
# configuration code:
|
38
|
+
task = {
|
39
|
+
# Account for Health Planet
|
40
|
+
'login_id' => config.param('login_id', :string),
|
41
|
+
'password' => config.param('password', :string),
|
42
|
+
# Credential for embulk-input-healthplanet, application type "Client Application"
|
43
|
+
'client_id' => config.param('client_id', :string),
|
44
|
+
'client_secret' => config.param('client_secret', :string),
|
45
|
+
# This plugin retrieves new data after this time
|
46
|
+
'next_from' => config.param('next_from', :string, :default => nil)
|
47
|
+
}
|
48
|
+
|
49
|
+
columns = [
|
50
|
+
Column.new(0, 'time', :timestamp),
|
51
|
+
Column.new(1, 'model', :string),
|
52
|
+
Column.new(2, 'weight', :double),
|
53
|
+
Column.new(3, 'body fat %', :double),
|
54
|
+
Column.new(4, 'muscle mass', :double),
|
55
|
+
Column.new(5, 'muscle score', :long),
|
56
|
+
Column.new(6, 'visceral fat level 2', :double),
|
57
|
+
Column.new(7, 'visceral fat level 1', :long),
|
58
|
+
Column.new(8, 'basal metabolic rate', :long),
|
59
|
+
Column.new(9, 'metabolic age', :long),
|
60
|
+
Column.new(10, 'estimated bone mass', :double),
|
61
|
+
# Not supported by Health Planet API Ver. 1.0
|
62
|
+
# Column.new(11, 'body water mass', :string),
|
63
|
+
]
|
64
|
+
|
65
|
+
resume(task, columns, 1, &control)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.resume(task, columns, count, &control)
|
69
|
+
task_reports = yield(task, columns, count)
|
70
|
+
|
71
|
+
next_config_diff = task_reports.first
|
72
|
+
return next_config_diff
|
73
|
+
end
|
74
|
+
|
75
|
+
def init
|
76
|
+
login_id = task['login_id']
|
77
|
+
password = task['password']
|
78
|
+
client_id = task['client_id']
|
79
|
+
client_secret = task['client_secret']
|
80
|
+
if task['next_from']
|
81
|
+
@next_from = Time.strptime(task['next_from'], '%Y-%m-%d %H:%M:%S')
|
82
|
+
end
|
83
|
+
|
84
|
+
# Setup connection
|
85
|
+
@conn = Faraday.new(:url => 'https://www.healthplanet.jp') do |faraday|
|
86
|
+
faraday.request :url_encoded
|
87
|
+
faraday.response :logger
|
88
|
+
faraday.use :cookie_jar
|
89
|
+
faraday.adapter Faraday.default_adapter
|
90
|
+
end
|
91
|
+
|
92
|
+
# Request Authentication page: /oauth/auth
|
93
|
+
response = @conn.get do |req|
|
94
|
+
req.url '/oauth/auth'
|
95
|
+
req.params[:client_id] = client_id
|
96
|
+
req.params[:redirect_uri] = REDIRECT_URI
|
97
|
+
req.params[:scope] = DEFAULT_SCOPE
|
98
|
+
req.params[:response_type] = DEFAULT_RESPONSE_TYPE
|
99
|
+
end
|
100
|
+
|
101
|
+
# Login and set session information
|
102
|
+
response = @conn.post 'login_oauth.do', { :loginId => login_id, :passwd => password, :send => '1', :url => "https://www.healthplanet.jp/oauth/auth?client_id=#{client_id}&redirect_uri=#{REDIRECT_URI}&scope=#{DEFAULT_SCOPE}&response_type=#{DEFAULT_RESPONSE_TYPE}" }
|
103
|
+
|
104
|
+
unless response.status == 302
|
105
|
+
# TODO return error in Embulk manner
|
106
|
+
print "Login failure\n"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get auth page again with JSESSIONID
|
110
|
+
response = @conn.get do |req|
|
111
|
+
req.url '/oauth/auth'
|
112
|
+
req.params[:client_id] = client_id
|
113
|
+
req.params[:redirect_uri] = REDIRECT_URI
|
114
|
+
req.params[:scope] = DEFAULT_SCOPE
|
115
|
+
req.params[:response_type] = DEFAULT_RESPONSE_TYPE
|
116
|
+
end
|
117
|
+
|
118
|
+
# Read oauth_token
|
119
|
+
document = Oga.parse_html(NKF.nkf('-Sw', response.body))
|
120
|
+
oauth_token = document.at_xpath('//input[@name="oauth_token"]').get('value')
|
121
|
+
|
122
|
+
# Post /oauth/approval.do
|
123
|
+
response = @conn.post '/oauth/approval.do', { :approval => 'true', :oauth_token => oauth_token }
|
124
|
+
|
125
|
+
# Read code
|
126
|
+
document = Oga.parse_html(NKF.nkf('-Sw', response.body))
|
127
|
+
code = document.at_xpath('//textarea[@id="code"]').text
|
128
|
+
|
129
|
+
# Get request token
|
130
|
+
response = @conn.post do |req|
|
131
|
+
req.url '/oauth/token'
|
132
|
+
req.params[:client_id] = client_id
|
133
|
+
req.params[:client_secret] = client_secret
|
134
|
+
req.params[:redirect_uri] = REDIRECT_URI
|
135
|
+
req.params[:code] = code
|
136
|
+
req.params[:grant_type] = DEFAULT_GRANT_TYPE
|
137
|
+
end
|
138
|
+
|
139
|
+
tokens = JSON.parse(response.body)
|
140
|
+
@access_token = tokens['access_token']
|
141
|
+
end
|
142
|
+
|
143
|
+
def run
|
144
|
+
from = @next_from.nil? ? (Time.now - DEFAULT_FROM_TIME) : @next_from
|
145
|
+
last_date = nil
|
146
|
+
|
147
|
+
while from < Time.now
|
148
|
+
to = from + RESPONSE_INTERVAL
|
149
|
+
date = innerscan(from, to)
|
150
|
+
# Update last_date if any data exists
|
151
|
+
last_date = date if date
|
152
|
+
|
153
|
+
# Next request must start from 1 minute later to avoid redundant data
|
154
|
+
from = to + 60
|
155
|
+
end
|
156
|
+
|
157
|
+
page_builder.finish
|
158
|
+
|
159
|
+
task_report = {}
|
160
|
+
unless preview? or last_date.nil?
|
161
|
+
# Next request must start from 1 minute later to avoid redundant data
|
162
|
+
task_report = { :next_from => (last_date + 60).strftime('%Y-%m-%d %H:%M:%S') }
|
163
|
+
end
|
164
|
+
return task_report
|
165
|
+
end
|
166
|
+
|
167
|
+
def innerscan(from = nil, to = nil)
|
168
|
+
response = @conn.get do |req|
|
169
|
+
req.url 'status/innerscan.json'
|
170
|
+
req.params[:access_token] = @access_token
|
171
|
+
# 0: registered time, 1: measured time
|
172
|
+
req.params[:date] = 1
|
173
|
+
req.params[:from] = from.strftime('%Y%m%d%H%M%S') unless from.nil?
|
174
|
+
req.params[:to] = to.strftime('%Y%m%d%H%M%S') unless to.nil?
|
175
|
+
req.params[:tag] = ALL_TAGS
|
176
|
+
end
|
177
|
+
|
178
|
+
data = JSON.parse(response.body)
|
179
|
+
|
180
|
+
result = {}
|
181
|
+
|
182
|
+
data['data'].each do |record|
|
183
|
+
date = Time.strptime(record['date'], '%Y%m%d%H%M')
|
184
|
+
|
185
|
+
result[date] ||= {}
|
186
|
+
result[date]['model'] ||= record['model']
|
187
|
+
result[date][record['tag']] = record['keydata']
|
188
|
+
end
|
189
|
+
|
190
|
+
dates = result.keys.sort
|
191
|
+
last_date = dates.last
|
192
|
+
|
193
|
+
dates.each do |date|
|
194
|
+
page = Array.new(11)
|
195
|
+
page[0] = date
|
196
|
+
result[date].each do |key, value|
|
197
|
+
case key
|
198
|
+
when 'model'
|
199
|
+
page[1] = value
|
200
|
+
when '6021'
|
201
|
+
# weight
|
202
|
+
page[2] = value.to_f
|
203
|
+
when '6022'
|
204
|
+
# body fat %
|
205
|
+
page[3] = value.to_f
|
206
|
+
when '6023'
|
207
|
+
# muscle mass
|
208
|
+
page[4] = value.to_f
|
209
|
+
when '6024'
|
210
|
+
# muscle score
|
211
|
+
page[5] = value.to_i
|
212
|
+
when '6025'
|
213
|
+
# visceral fat level 2
|
214
|
+
page[6] = value.to_f
|
215
|
+
when '6026'
|
216
|
+
# visceral fat level 1
|
217
|
+
page[7] = value.to_i
|
218
|
+
when '6027'
|
219
|
+
# basal metabolic rate
|
220
|
+
page[8] = value.to_i
|
221
|
+
when '6028'
|
222
|
+
# metabolic age
|
223
|
+
page[9] = value.to_i
|
224
|
+
when '6029'
|
225
|
+
# estimated bone mass
|
226
|
+
page[10] = value.to_f
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
page_builder.add(page)
|
231
|
+
end
|
232
|
+
|
233
|
+
last_date
|
234
|
+
end
|
235
|
+
|
236
|
+
def preview?
|
237
|
+
begin
|
238
|
+
org.embulk.spi.Exec.isPreview()
|
239
|
+
rescue java.lang.NullPointerException => e
|
240
|
+
false
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: embulk-input-healthplanet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Masahiro Yoshizawa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: embulk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.7.10
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.7.10
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.11
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.8.11
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday-cookie_jar
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.0.6
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.0.6
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: oga
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.0.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.0.0
|
97
|
+
description: Retrieve your innerscan data through Health Planet API v1.
|
98
|
+
email:
|
99
|
+
- muziyoshiz@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .ruby-version
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- embulk-input-healthplanet.gemspec
|
111
|
+
- lib/embulk/input/healthplanet.rb
|
112
|
+
homepage: https://github.com/muziyoshiz/embulk-input-healthplanet
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
requirements: []
|
131
|
+
rubyforge_project:
|
132
|
+
rubygems_version: 2.0.14
|
133
|
+
signing_key:
|
134
|
+
specification_version: 4
|
135
|
+
summary: Healthplanet input plugin for Embulk
|
136
|
+
test_files: []
|