simplificator-withings 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
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,6 @@
1
+ require 'httparty'
2
+ require 'digest/md5'
3
+
4
+ %w(base notification_description connection measurement_group error user).each do |part|
5
+ require File.join(File.dirname(__FILE__), 'withings', part)
6
+ end
@@ -0,0 +1,14 @@
1
+ module Withings
2
+ end
3
+
4
+ # Copied over from ActiveSupport
5
+ unless Hash.new.respond_to?(:stringify_keys)
6
+ class Hash
7
+ def stringify_keys
8
+ inject({}) do |options, (key, value)|
9
+ options[key.to_s] = value
10
+ options
11
+ end
12
+ end
13
+ end
14
+ end
@@ -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
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'withings'
9
+
10
+ class Test::Unit::TestCase
11
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestSimplificatorWithings < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -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