simplificator-withings 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +36 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/lib/withings.rb +6 -0
- data/lib/withings/base.rb +14 -0
- data/lib/withings/connection.rb +31 -0
- data/lib/withings/error.rb +23 -0
- data/lib/withings/measurement_group.rb +71 -0
- data/lib/withings/notification_description.rb +13 -0
- data/lib/withings/user.rb +110 -0
- data/sample.rb +29 -0
- data/test/helper.rb +11 -0
- data/test/test_simplificator-withings.rb +7 -0
- data/test/users_test.rb +119 -0
- metadata +127 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 pascalbetz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= simplificator-withings
|
2
|
+
|
3
|
+
This is a ruby implementation for the Withings API. Description of the API can be found here: http://www.withings.com/en/api/
|
4
|
+
|
5
|
+
== How To ==
|
6
|
+
|
7
|
+
See sample.rb
|
8
|
+
|
9
|
+
== Note on keys in hashes
|
10
|
+
|
11
|
+
Keys to constructors (User, MeasurementGroup and NotificationDescription) and methods (User.measurement_groups)
|
12
|
+
can be either of String or Symbol
|
13
|
+
|
14
|
+
== Note on naming convention
|
15
|
+
|
16
|
+
The WBS API has parameter with shortened names (e.g. 'grpid') or names not following a consistent naming pattern. While this
|
17
|
+
API implementation tries to stick as close to the API as possible it also tries to unify and simplify the parameter names.
|
18
|
+
The constructors for User, MeasurementGroup and NotificationDescription accept the names provided by the API but convert the names then
|
19
|
+
to a more "ruby" way.
|
20
|
+
An exception to this are the "id" and "publickey" parameters for User.new, they are accepted as "user_id" and "public_key" as well.
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
== Note on Patches/Pull Requests
|
25
|
+
|
26
|
+
* Fork the project.
|
27
|
+
* Make your feature addition or bug fix.
|
28
|
+
* Add tests for it. This is important so I don't break it in a
|
29
|
+
future version unintentionally.
|
30
|
+
* Commit, do not mess with rakefile, version, or history.
|
31
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
32
|
+
* Send me a pull request. Bonus points for topic branches.
|
33
|
+
|
34
|
+
== Copyright
|
35
|
+
|
36
|
+
Copyright (c) 2010 simplificator. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "simplificator-withings"
|
8
|
+
gem.summary = %Q{API implementation for withings.com}
|
9
|
+
gem.description = %Q{A withings API implementation in ruby. Created for the evita project}
|
10
|
+
gem.email = "info@simplificator.com"
|
11
|
+
gem.homepage = "http://github.com/simplificator/simplificator-withings"
|
12
|
+
gem.authors = ["pascalbetz"]
|
13
|
+
gem.add_development_dependency 'shoulda'
|
14
|
+
gem.add_development_dependency 'mocha'
|
15
|
+
gem.add_dependency('httparty')
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/test_*.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'rcov/rcovtask'
|
32
|
+
Rcov::RcovTask.new do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.pattern = 'test/**/test_*.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
task :rcov do
|
39
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
task :test => :check_dependencies
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "simplificator-withings #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/withings.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Withings::Connection
|
2
|
+
include HTTParty
|
3
|
+
base_uri 'wbsapi.withings.net'
|
4
|
+
format :json
|
5
|
+
|
6
|
+
attr_reader :user
|
7
|
+
def initialize(user)
|
8
|
+
@user = user
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_request(path, params)
|
12
|
+
response = self.get(path, :query => params)
|
13
|
+
verify_response!(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_request(path, params)
|
17
|
+
response = self.class.get(path, :query => params.merge(:publickey => user.public_key, :userid => user.user_id))
|
18
|
+
self.class.verify_response!(response)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def self.verify_response!(response)
|
23
|
+
if response['status'] == 0
|
24
|
+
response['body'] || response['status']
|
25
|
+
else
|
26
|
+
raise ApiError.new(response['status'])
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Withings::ApiError < StandardError
|
2
|
+
STATUS_CODES = {
|
3
|
+
100 => "The hash is missing, invalid, or does not match the provided email",
|
4
|
+
247 => "The userid is either absent or incorrect",
|
5
|
+
250 => "The userid and publickey provided do not match, or the user does not share its data",
|
6
|
+
264 => "The email address provided is either unknown or invalid",
|
7
|
+
293 => "The callback URL is either absent or incorrect",
|
8
|
+
294 => "No such subscription could be deleted",
|
9
|
+
304 => "The comment is either absent or incorrect",
|
10
|
+
2554 => "Invalid Parameters . Not sure about this error message, it's not documented",
|
11
|
+
2555 => "An unknown error occurred",
|
12
|
+
}
|
13
|
+
|
14
|
+
attr_reader :status
|
15
|
+
def initialize(status)
|
16
|
+
super(STATUS_CODES[status] || 'Undefined status code')
|
17
|
+
@status = status
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
super + " - Status code: #{self.status}"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Withings::MeasurementGroup
|
2
|
+
ATTRIBUTION_SCALE = 0
|
3
|
+
ATTRIBUTION_SCALE_AMBIGUOUS = 1
|
4
|
+
ATTRIBUTION_SCALE_MANUALLY = 2
|
5
|
+
ATTRIBUTION_SCALE_MANUALLY_DURING_CREATION = 4
|
6
|
+
|
7
|
+
CATEGORY_MEASURE = 1
|
8
|
+
CATEGORY_TARGET = 2
|
9
|
+
|
10
|
+
TYPE_WEIGHT = 1
|
11
|
+
TYPE_SIZE = 4
|
12
|
+
TYPE_FAT_FREE_MASS_WEIGHT = 5
|
13
|
+
TYPE_FAT_RATIO = 6
|
14
|
+
TYPE_FAT_MASS_WEIGHT = 8
|
15
|
+
|
16
|
+
attr_reader :group_id, :attribution, :created_at, :category
|
17
|
+
attr_reader :weight, :height, :fat
|
18
|
+
def initialize(params)
|
19
|
+
params = params.keys_as_string
|
20
|
+
@group_id = params['grpid']
|
21
|
+
@attribution = params['attrib']
|
22
|
+
@created_at = Time.at(params['date'])
|
23
|
+
@category = params['category']
|
24
|
+
params['measures'].each do |measure|
|
25
|
+
value = (measure['value'] * 10 ** measure['unit']).to_f
|
26
|
+
case measure['type']
|
27
|
+
when TYPE_WEIGHT then @weight = value
|
28
|
+
when TYPE_SIZE then @height = value
|
29
|
+
when TYPE_FAT_MASS_WEIGHT then @fat = value
|
30
|
+
when TYPE_FAT_RATIO, TYPE_FAT_FREE_MASS_WEIGHT
|
31
|
+
else raise "Unknown #{measure.inspect}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def measure?
|
37
|
+
self.category == CATEGORY_MEASURE
|
38
|
+
end
|
39
|
+
|
40
|
+
def target?
|
41
|
+
self.category == CATEGORY_TARGET
|
42
|
+
end
|
43
|
+
|
44
|
+
# while fat_ratio and fat_free_mass_weight is provided by the API as well i've seen responses where they were not included. Since
|
45
|
+
# they can be calculated as soon as weight and fat is provided we do it ourselves
|
46
|
+
def fat_ratio
|
47
|
+
(self.weight / self.fat) if self.weight && self.fat
|
48
|
+
end
|
49
|
+
|
50
|
+
def fat_free_weight
|
51
|
+
(self.weight - self.fat) if self.weight && self.fat
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def bmi
|
56
|
+
if self.height && self.weight
|
57
|
+
self.weight / (self.height ** 2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
"[ Weight: #{self.weight}, Fat: #{self.fat}, Height: #{self.height}, BMI: #{self.bmi}, Ratio: #{self.fat_ratio}, Free: #{self.fat_free_weight}, ID: #{self.group_id}]"
|
63
|
+
end
|
64
|
+
|
65
|
+
def inspect
|
66
|
+
self.to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Withings::NotificationDescription
|
2
|
+
attr_reader :callback_url, :description, :expires_at
|
3
|
+
def initialize(params = {})
|
4
|
+
params = params.stringify_keys
|
5
|
+
@callback_url = params['callbackurl']
|
6
|
+
@description = params['comment']
|
7
|
+
@expires_at = Time.at(params['expires'])
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"[Notification #{self.callback_url} / #{self.description}, #{self.expires_at}]"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
class Withings::User
|
2
|
+
# Authenticate by email and password
|
3
|
+
def self.by_email(email, password)
|
4
|
+
response = Connection.get_request('/account', :action => :getuserslist, :email => email, :hash => auth_hash(email, password))
|
5
|
+
User.new(response['users'].first)
|
6
|
+
end
|
7
|
+
# Authenticate by user id and public key
|
8
|
+
def self.by_user_id(user_id, public_key)
|
9
|
+
response = Connection.get_request('/account', :action => :getbyuserid, :userid => user_id, :publickey => public_key)
|
10
|
+
User.new(response['users'].first)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
attr_reader :short_name, :public_key, :user_id, :birthdate, :fat_method, :first_name, :last_name, :gender
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# If you create a user yourself, then the only attributes of interest (required for calls to the API) are 'user_id' and 'public_key'
|
19
|
+
#
|
20
|
+
def initialize(params)
|
21
|
+
params = params.stringify_keys
|
22
|
+
@short_name = params['shortname']
|
23
|
+
@first_name = params['firstname']
|
24
|
+
@last_name = params['lastname']
|
25
|
+
@public_key = params['publickey'] || params['public_key']
|
26
|
+
@user_id = params['id'] || params['user_id']
|
27
|
+
@share = params['ispublic'] == 1 ? true : false
|
28
|
+
@birthdate = Time.at(params['birthdate']) if params['birthdate']
|
29
|
+
@gender = params['gender'] == 0 ? :male : params['gender'] == 1 ? :female : nil
|
30
|
+
@fat_method = params['fatmethod']
|
31
|
+
end
|
32
|
+
|
33
|
+
def subscribe_to_notification(callback_url, description)
|
34
|
+
connection.get_request('/notify', :action => :subscribe, :callbackurl => callback_url, :comment => description)
|
35
|
+
end
|
36
|
+
|
37
|
+
def revoke_notification(callback_url)
|
38
|
+
connection.get_request('/notify', :action => :revoke, :callbackurl => callback_url)
|
39
|
+
end
|
40
|
+
|
41
|
+
def describe_notification(callback_url)
|
42
|
+
response = connection.get_request('/notify', :action => :get, :callbackurl => callback_url)
|
43
|
+
NotificationDescription.new(response.merge(:callbackurl => callback_url))
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# list measurement groups
|
48
|
+
# - :per_page
|
49
|
+
# - :page
|
50
|
+
# - :category
|
51
|
+
# - :measurement_type
|
52
|
+
# - :start_at
|
53
|
+
# - :end_at
|
54
|
+
# - :last_udpated_at
|
55
|
+
#
|
56
|
+
# Parameters are described in WBS api, names are "rubyfied" (startdate -> start_at and so on)
|
57
|
+
def measurement_groups(params = {})
|
58
|
+
params = params.stringify_keys
|
59
|
+
options = {:limit => 100, :offset => 0}
|
60
|
+
options[:meastype] = params[:measurement_type] if params.has_key?(:measurement_type)
|
61
|
+
options[:category] = params[:category] if params.has_key?(:category)
|
62
|
+
options[:limit] = params[:per_page] if params.has_key?(:per_page)
|
63
|
+
options[:offset] = ((params[:page] || 1) - 1) * options[:limit]
|
64
|
+
options[:startdate] = params[:start_at].to_i if params[:start_at]
|
65
|
+
options[:enddate] = params[:end_at].to_i if params[:end_at]
|
66
|
+
options[:lastupdate] = params[:last_update].to_i if params[:last_updated_at]
|
67
|
+
|
68
|
+
response = connection.get_request('/measure', options.merge(:action => :getmeas))
|
69
|
+
response['measuregrps'].map do |group|
|
70
|
+
MeasurementGroup.new(group)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# enable or disable sharing
|
75
|
+
def share=(value)
|
76
|
+
@share = value
|
77
|
+
connection.get_request('/user', :action => :update, :ispublic => is_public?)
|
78
|
+
end
|
79
|
+
|
80
|
+
# sharing enabled?
|
81
|
+
def share?
|
82
|
+
@share
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_s
|
86
|
+
"[User #{short_name} / #{:user_id} / #{sharing?}]"
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
protected
|
91
|
+
|
92
|
+
def connection
|
93
|
+
@connection ||= Connection.new(self)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.auth_hash(email, password)
|
97
|
+
hashed_password = Digest::MD5.hexdigest(password)
|
98
|
+
Digest::MD5.hexdigest("#{email}:#{hashed_password}:#{once}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.once()
|
102
|
+
Connection.get_request('/once', :action => :get)['once']
|
103
|
+
end
|
104
|
+
|
105
|
+
# convert from boolean (@share) to 1/0 as required by the API
|
106
|
+
def is_public?
|
107
|
+
@share ? 1 : 0
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
data/sample.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'lib/withings'
|
3
|
+
|
4
|
+
# All classes are name-spaced
|
5
|
+
include Withings
|
6
|
+
|
7
|
+
# A user can be authenticated with email address and password
|
8
|
+
user = User.by_email('<YOUR EMAIL ADDRESS>', '<YOUR PASSWORD>')
|
9
|
+
|
10
|
+
# Or you can fetch details if you have the user id and public key
|
11
|
+
user = User.by_user_id('<YOUR USER ID>', '<YOUR PUBLIC KEY>')
|
12
|
+
|
13
|
+
# or if you already have user id and public key, you can create ir yourself
|
14
|
+
user = User.new(:user_id => '<YOUR USER ID>', :public_key => '<YOUR PUBLIC_KEY>')
|
15
|
+
|
16
|
+
# enable/disable sharing, disabling it will reset the public key
|
17
|
+
user.share=true
|
18
|
+
|
19
|
+
# subscribe for notification for url and pass a description
|
20
|
+
user.subscribe_notification('http://foo.bar.com', 'test')
|
21
|
+
|
22
|
+
# describe the notification for a given url, this is important for expiration dates
|
23
|
+
user.describe_notification('http://foo.bar.com')
|
24
|
+
|
25
|
+
# revoke notification for an url
|
26
|
+
user.revoke_notification('http://foo.bar.com')
|
27
|
+
|
28
|
+
# list measurement groups
|
29
|
+
puts user.measurement_groups(:per_page => 10, :page => 1, :end_at => Time.now).join("\n")
|
data/test/helper.rb
ADDED
data/test/users_test.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
include Withings
|
4
|
+
|
5
|
+
class UsersTest < Test::Unit::TestCase
|
6
|
+
context 'test connection calls' do
|
7
|
+
setup do
|
8
|
+
@user = User.new('user_id' => 12345, 'public_key' => 67890)
|
9
|
+
end
|
10
|
+
should 'update user' do
|
11
|
+
Withings::Connection.any_instance.expects(:get_request).with('/user', :action => :update, :ispublic => 1)
|
12
|
+
@user.share = true
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'subscribe to notification' do
|
16
|
+
Withings::Connection.any_instance.expects(:get_request).with('/notify', :action => :subscribe, :callbackurl => 'http://schni.com', :comment => 'descri')
|
17
|
+
@user.subscribe_to_notification('http://schni.com', 'descri')
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'revoke notification' do
|
21
|
+
Withings::Connection.any_instance.expects(:get_request).with('/notify', :action => :revoke, :callbackurl => 'http://schni.com')
|
22
|
+
@user.revoke_notification('http://schni.com')
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'describe notification' do
|
26
|
+
setup do
|
27
|
+
Withings::Connection.
|
28
|
+
any_instance.expects(:get_request).with('/notify', :action => :get, :callbackurl => 'http://schni.com').
|
29
|
+
returns({'comment' => 'blabla', 'expires' => 1234})
|
30
|
+
@description = @user.describe_notification('http://schni.com')
|
31
|
+
end
|
32
|
+
should 'merge the callback url into the descripton' do
|
33
|
+
assert_equal 'http://schni.com', @description.callback_url
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'contain the expires_at time' do
|
37
|
+
assert_equal Time.at(1234), @description.expires_at
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'contain the description' do
|
41
|
+
assert_equal 'blabla', @description.description
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'authentication by email' do
|
47
|
+
setup do
|
48
|
+
password = 'kongking'
|
49
|
+
email = 'king@kong.com'
|
50
|
+
once = 'abcdef'
|
51
|
+
hashed = Digest::MD5.hexdigest("#{email}:#{Digest::MD5.hexdigest(password)}:#{once}")
|
52
|
+
Connection.expects(:get_request).with('/once', :action => :get).returns({'once' => once})
|
53
|
+
Connection.expects(:get_request).with('/account', :action => :getuserslist, :email => email, :hash => hashed).
|
54
|
+
returns({'users' => [{}]})
|
55
|
+
end
|
56
|
+
should 'authenticate with hashed password' do
|
57
|
+
User.by_email('king@kong.com', 'kongking')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'authentication by user_id' do
|
62
|
+
setup do
|
63
|
+
user_id = 'kongking'
|
64
|
+
public_key = 'abcdef'
|
65
|
+
Connection.expects(:get_request).with('/account', :action => :getbyuserid, :userid => user_id, :publickey => public_key).
|
66
|
+
returns({'users' => [{}]})
|
67
|
+
end
|
68
|
+
should 'authenticate with hashed password' do
|
69
|
+
User.by_user_id('kongking', 'abcdef')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
context 'constructor' do
|
75
|
+
should 'assign short_name' do
|
76
|
+
assert_equal 'Pascal', User.new('shortname' => 'Pascal').short_name
|
77
|
+
end
|
78
|
+
should 'assign first_name' do
|
79
|
+
assert_equal 'Pascal', User.new('firstname' => 'Pascal').first_name
|
80
|
+
end
|
81
|
+
should 'assign last_name' do
|
82
|
+
assert_equal 'Pascal', User.new('lastname' => 'Pascal').last_name
|
83
|
+
end
|
84
|
+
|
85
|
+
should 'assign public_key' do
|
86
|
+
assert_equal '1234', User.new('publickey' => '1234').public_key
|
87
|
+
end
|
88
|
+
should 'assign public_key with alternative key' do
|
89
|
+
assert_equal '1234', User.new('public_key' => '1234').public_key
|
90
|
+
end
|
91
|
+
|
92
|
+
should 'assign user_id' do
|
93
|
+
assert_equal '1234', User.new('id' => '1234').user_id
|
94
|
+
end
|
95
|
+
should 'assign user_id with alternative key' do
|
96
|
+
assert_equal '1234', User.new('user_id' => '1234').user_id
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
should 'assign share (to true)' do
|
101
|
+
assert_equal true, User.new('ispublic' => 1).share?
|
102
|
+
end
|
103
|
+
should 'assign share (to false)' do
|
104
|
+
assert_equal false, User.new('ispublic' => 0).share?
|
105
|
+
end
|
106
|
+
|
107
|
+
should 'assign gender (to true)' do
|
108
|
+
assert_equal :male, User.new('gender' => 0).gender
|
109
|
+
end
|
110
|
+
should 'assign gender (to false)' do
|
111
|
+
assert_equal :female, User.new('gender' => 1).gender
|
112
|
+
end
|
113
|
+
|
114
|
+
should 'assign fatmethod' do
|
115
|
+
assert_equal 2, User.new('fatmethod' => 2).fat_method
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simplificator-withings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- pascalbetz
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-02 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: shoulda
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mocha
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: httparty
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
description: A withings API implementation in ruby. Created for the evita project
|
64
|
+
email: info@simplificator.com
|
65
|
+
executables: []
|
66
|
+
|
67
|
+
extensions: []
|
68
|
+
|
69
|
+
extra_rdoc_files:
|
70
|
+
- LICENSE
|
71
|
+
- README.rdoc
|
72
|
+
files:
|
73
|
+
- .document
|
74
|
+
- .gitignore
|
75
|
+
- LICENSE
|
76
|
+
- README.rdoc
|
77
|
+
- Rakefile
|
78
|
+
- VERSION
|
79
|
+
- lib/withings.rb
|
80
|
+
- lib/withings/base.rb
|
81
|
+
- lib/withings/connection.rb
|
82
|
+
- lib/withings/error.rb
|
83
|
+
- lib/withings/measurement_group.rb
|
84
|
+
- lib/withings/notification_description.rb
|
85
|
+
- lib/withings/user.rb
|
86
|
+
- sample.rb
|
87
|
+
- test/helper.rb
|
88
|
+
- test/test_simplificator-withings.rb
|
89
|
+
- test/users_test.rb
|
90
|
+
has_rdoc: true
|
91
|
+
homepage: http://github.com/simplificator/simplificator-withings
|
92
|
+
licenses: []
|
93
|
+
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options:
|
96
|
+
- --charset=UTF-8
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.3.7
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: API implementation for withings.com
|
124
|
+
test_files:
|
125
|
+
- test/helper.rb
|
126
|
+
- test/test_simplificator-withings.rb
|
127
|
+
- test/users_test.rb
|