simplificator-withings 0.1.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.
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