cs 0.1.0beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +7 -0
- data/cs.gemspec +22 -0
- data/lib/commonsense-ruby-lib.rb +127 -0
- data/lib/commonsense-ruby-lib/auth/http.rb +117 -0
- data/lib/commonsense-ruby-lib/auth/oauth.rb +101 -0
- data/lib/commonsense-ruby-lib/end_point.rb +276 -0
- data/lib/commonsense-ruby-lib/end_point/group.rb +28 -0
- data/lib/commonsense-ruby-lib/end_point/sensor.rb +36 -0
- data/lib/commonsense-ruby-lib/end_point/sensor_data.rb +70 -0
- data/lib/commonsense-ruby-lib/end_point/user.rb +50 -0
- data/lib/commonsense-ruby-lib/error.rb +51 -0
- data/lib/commonsense-ruby-lib/relation.rb +233 -0
- data/lib/commonsense-ruby-lib/relation/sensor_data_relation.rb +116 -0
- data/lib/commonsense-ruby-lib/relation/sensor_relation.rb +162 -0
- data/lib/commonsense-ruby-lib/serializer.rb +20 -0
- data/lib/commonsense-ruby-lib/session.rb +105 -0
- data/lib/commonsense-ruby-lib/version.rb +3 -0
- data/spec/features/sensor_data_management_spec.rb +4 -0
- data/spec/features/sensor_management_spec.rb +105 -0
- data/spec/features/user_management_spec.rb +70 -0
- data/spec/lib/commonsense-ruby-lib/end_point/sensor_data_spec.rb +68 -0
- data/spec/lib/commonsense-ruby-lib/end_point/sensor_spec.rb +98 -0
- data/spec/lib/commonsense-ruby-lib/end_point/user_spec.rb +36 -0
- data/spec/lib/commonsense-ruby-lib/end_point_spec.rb +190 -0
- data/spec/lib/commonsense-ruby-lib/relation/sensor_data_relation_spec.rb +444 -0
- data/spec/lib/commonsense-ruby-lib/relation/sensor_relation_spec.rb +165 -0
- data/spec/lib/commonsense-ruby-lib/session_spec.rb +43 -0
- data/spec/lib/commonsense-ruby-lib_spec.rb +51 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/spec_config.yml.sample +6 -0
- data/spec/support/vcr.rb +5 -0
- metadata +175 -0
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.rspec
|
6
|
+
.autotest
|
7
|
+
.yardoc
|
8
|
+
Gemfile.lock
|
9
|
+
InstalledFiles
|
10
|
+
_yardoc
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
spec/vcr
|
21
|
+
spec/support/spec_config.yml
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ahmy Yulrizka
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# Commonsense::Ruby::Lib
|
2
|
+
Client library to communicate with CommonSense written in ruby
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
gem 'commonsense-ruby-lib'
|
9
|
+
|
10
|
+
And then execute:
|
11
|
+
|
12
|
+
$ bundle
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install commonsense-ruby-lib
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
### Authentication
|
21
|
+
```ruby
|
22
|
+
client = CommonSense::Client.new
|
23
|
+
client.login('username','password')
|
24
|
+
|
25
|
+
# get current user
|
26
|
+
current_user = client.current_user
|
27
|
+
```
|
28
|
+
|
29
|
+
### Querying Sensor
|
30
|
+
```ruby
|
31
|
+
# create sensors relation
|
32
|
+
sensors = client.sensors
|
33
|
+
|
34
|
+
# is the same as
|
35
|
+
sensors = CommonSense::Relation::Sensors.new
|
36
|
+
sensors.session = session
|
37
|
+
|
38
|
+
# Get all sensor
|
39
|
+
sensors = client.sensors
|
40
|
+
sensors.to_a
|
41
|
+
|
42
|
+
# Get sensor by specifying parameters
|
43
|
+
client.sensors.where(page: 0, per_page: 1000)
|
44
|
+
client.sensors.where(owned: true)
|
45
|
+
client.sensors.where(physical: true)
|
46
|
+
client.sensors.where(page: 0, per_page: 1000, physical: true, owned: true, details: "full")
|
47
|
+
|
48
|
+
# process each sensor
|
49
|
+
client.sensors.where(owned: true).each {|sensor| puts sensor.name}
|
50
|
+
|
51
|
+
# Chain parameters
|
52
|
+
client.sensors.where(page:0, per_page: 10).where(physical: true)
|
53
|
+
|
54
|
+
# Find sensor by name
|
55
|
+
client.sensors.find_by_name(/position/)
|
56
|
+
client.sensors.find_by_name(/position/, owned: true) # or
|
57
|
+
client.sensors.where(owned: true).find_by_name(/position/)
|
58
|
+
|
59
|
+
# Get first sensor or last sensor
|
60
|
+
sensor = client.sensors.first
|
61
|
+
sensor = client.sensors.last
|
62
|
+
|
63
|
+
# Get number of sensors
|
64
|
+
client.sensors.count
|
65
|
+
client.sensors.where(owned: true).count
|
66
|
+
```
|
67
|
+
|
68
|
+
### Creating Sensor
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
sensor = client.sensor.build
|
72
|
+
sensor.name = "light"
|
73
|
+
sensor.display_name = "Light"
|
74
|
+
sensor.device_type = "Android"
|
75
|
+
sensor.pager_type = ""
|
76
|
+
sensor.data_type = "json"
|
77
|
+
sensor.data_structure = {lux: "integer"}
|
78
|
+
sensor.save!
|
79
|
+
```
|
80
|
+
|
81
|
+
### Uploading data point
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# Find the first position sensor
|
85
|
+
sensor = client.sensors.find_by_name(/position/).first
|
86
|
+
|
87
|
+
# save data point
|
88
|
+
data = sensor.data.build
|
89
|
+
data.date = Time.now
|
90
|
+
data.value = {"lux" => 1}
|
91
|
+
data.save!
|
92
|
+
|
93
|
+
# more compact version
|
94
|
+
sensor.data.build(date: Time.now, value: {"lux" => 1}).save!
|
95
|
+
```
|
96
|
+
|
97
|
+
### Debuging
|
98
|
+
|
99
|
+
To get information about the API response (body, code, headers) inspect the session
|
100
|
+
|
101
|
+
example
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
# do some API call
|
105
|
+
current_user = client.current_user
|
106
|
+
|
107
|
+
# get the session
|
108
|
+
session = client.session
|
109
|
+
|
110
|
+
response_code = session.response_code
|
111
|
+
response_body = session.resopnse_body
|
112
|
+
header = session.response_headers
|
113
|
+
|
114
|
+
# dump the output to text file
|
115
|
+
session.dump_to_text("/tmp/output.txt")
|
116
|
+
|
117
|
+
# open output in browser. Require 'launchy' gem
|
118
|
+
session.open_in_browser
|
119
|
+
```
|
120
|
+
|
121
|
+
## Testing
|
122
|
+
|
123
|
+
$ cp spec/support/spec_config.yml.sample spec/support/spec_config.yml
|
124
|
+
$ rspec
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
|
128
|
+
1. Fork it
|
129
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
130
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
131
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
132
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/cs.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/commonsense-ruby-lib/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Ahmy Yulrizka"]
|
6
|
+
gem.email = ["ahmy@sense-os.nl"]
|
7
|
+
gem.description = %q{CommonSense API client library}
|
8
|
+
gem.summary = %q{Client library to communicate with CommonSense written in ruby}
|
9
|
+
gem.homepage = "https://github.com/senseobservationsystems/commonsense-ruby-lib"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "cs"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = CommonSense::VERSION
|
17
|
+
gem.add_development_dependency("rspec", "~> 2.13.0")
|
18
|
+
gem.add_development_dependency("launchy", "~> 2.3.0")
|
19
|
+
gem.add_development_dependency("fakeweb", "~> 1.3.0")
|
20
|
+
gem.add_dependency('httparty', '~> 0.11.0')
|
21
|
+
gem.add_dependency('oauth', '~> 0.4.7')
|
22
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "commonsense-ruby-lib/version"
|
2
|
+
require "commonsense-ruby-lib/error"
|
3
|
+
require "commonsense-ruby-lib/auth/http"
|
4
|
+
require "commonsense-ruby-lib/auth/oauth"
|
5
|
+
require "commonsense-ruby-lib/session"
|
6
|
+
require "commonsense-ruby-lib/end_point"
|
7
|
+
require "commonsense-ruby-lib/end_point/user"
|
8
|
+
require "commonsense-ruby-lib/end_point/group"
|
9
|
+
require "commonsense-ruby-lib/end_point/sensor"
|
10
|
+
require "commonsense-ruby-lib/end_point/sensor_data"
|
11
|
+
require "commonsense-ruby-lib/relation"
|
12
|
+
require "commonsense-ruby-lib/relation/sensor_relation"
|
13
|
+
require "commonsense-ruby-lib/relation/sensor_data_relation"
|
14
|
+
|
15
|
+
module CommonSense
|
16
|
+
|
17
|
+
# Main entry class of the library.
|
18
|
+
#
|
19
|
+
# The login functionality always comes in two pair. The Bang (!) method
|
20
|
+
# will raise an exception when there is an error and the normal (without !)
|
21
|
+
# will return nil when it fails.
|
22
|
+
#
|
23
|
+
# The response can be viewed by looking at the {CommonSense::Session}
|
24
|
+
#
|
25
|
+
# client.session # will return the session object
|
26
|
+
#
|
27
|
+
# == Authentication with User And Password
|
28
|
+
#
|
29
|
+
# client = CommonSense::Client.new
|
30
|
+
# client.login('username', 'password')
|
31
|
+
#
|
32
|
+
# == Authentication using OAuth
|
33
|
+
#
|
34
|
+
# client = CommonSense::Client.new
|
35
|
+
# client.oauth('CONSUMER_KEY', 'CONSUMER_SECRET', 'ACCESS_TOKEN', 'ACCESS_TOKEN_SECRET')
|
36
|
+
#
|
37
|
+
# == Using different API server
|
38
|
+
#
|
39
|
+
# client = CommonSense::Client.new(base_uri: 'https://api.dev.sense-os.nl')
|
40
|
+
# # or
|
41
|
+
# client.base_uri = 'https://api.dev.sense-os.nl'
|
42
|
+
#
|
43
|
+
class Client
|
44
|
+
attr_accessor :session, :base_uri
|
45
|
+
|
46
|
+
def initialize(opts={})
|
47
|
+
options = {
|
48
|
+
base_uri: 'https://api.sense-os.nl',
|
49
|
+
}.merge(opts)
|
50
|
+
@base_uri = options[:base_uri]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create a new session to CommonSense using username and plain text password
|
54
|
+
# with `login!` it will throw exception if there is an error
|
55
|
+
#
|
56
|
+
# client = CommonSense::Client.new
|
57
|
+
# client.login!('username', 'password')
|
58
|
+
def login!(user, password)
|
59
|
+
@session = Session.new(base_uri: @base_uri)
|
60
|
+
@session.login(user, password)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Create a new session to CommonSense using username and plain text password
|
64
|
+
# with `login` it will return nil if it not successful
|
65
|
+
#
|
66
|
+
# client = CommonSense::Client.new
|
67
|
+
# client.login('username', 'password')
|
68
|
+
def login(user, password)
|
69
|
+
login!(user, password) rescue nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create a new session to CommonSense using OAuth credentials
|
73
|
+
#
|
74
|
+
# client = CommonSense::Client.new
|
75
|
+
# client.login('username', 'password')
|
76
|
+
def oauth(consumer_key, consumer_secret, access_token, access_token_secret)
|
77
|
+
@session = Session.new(base_uri: @base_uri)
|
78
|
+
@session.oauth(consumer_key, consumer_secret, access_token, access_token_secret)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create new session by manually specifiying `session_id` parameter
|
82
|
+
#
|
83
|
+
# client = CommonSense::Client.new
|
84
|
+
# client.session_id('12345')
|
85
|
+
def set_session_id(session_id)
|
86
|
+
@session = Session.new(base_uri: @base_uri)
|
87
|
+
@session.session_id = session_id
|
88
|
+
end
|
89
|
+
|
90
|
+
# Retrun logged in user
|
91
|
+
def current_user
|
92
|
+
user = EndPoint::User.new
|
93
|
+
user.session = @session
|
94
|
+
user.current_user
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create a new user
|
98
|
+
#
|
99
|
+
# client = CommonSense::Client.new
|
100
|
+
# client.new_user(username: 'Ahmy')
|
101
|
+
# client.email = 'ahmy@gmail.com'
|
102
|
+
# ...
|
103
|
+
# client.save!
|
104
|
+
def new_user(hash={})
|
105
|
+
user = EndPoint::User.new(hash)
|
106
|
+
user.session = Session.new(base_uri: @base_uri, authentication: false)
|
107
|
+
user
|
108
|
+
end
|
109
|
+
|
110
|
+
# @see CommonSense::Relation::SensorRelation
|
111
|
+
def sensors
|
112
|
+
Relation::SensorRelation.new(@session)
|
113
|
+
end
|
114
|
+
|
115
|
+
def current_groups
|
116
|
+
group = EndPoint::Group.new
|
117
|
+
group.session = @session
|
118
|
+
group.current_groups
|
119
|
+
end
|
120
|
+
|
121
|
+
# return errors got from session
|
122
|
+
def errors
|
123
|
+
return @session.errors if @session
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module CommonSense
|
5
|
+
module Auth
|
6
|
+
class HTTP
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
attr_accessor :response_body, :response_code, :response_headers, :errors
|
10
|
+
attr_reader :session_id
|
11
|
+
|
12
|
+
def initialize(base_uri = nil)
|
13
|
+
self.base_uri = base_uri
|
14
|
+
@session_id = nil
|
15
|
+
reset
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(path, query={}, headers = {})
|
19
|
+
reset
|
20
|
+
headers = default_headers.merge(headers)
|
21
|
+
options = {query: query, headers: headers}
|
22
|
+
@response_body = self.class.get(path, options)
|
23
|
+
parse_response
|
24
|
+
@response_body
|
25
|
+
end
|
26
|
+
|
27
|
+
def post(path, body = '', headers = {})
|
28
|
+
reset
|
29
|
+
headers = default_headers.merge(headers)
|
30
|
+
@response_body = self.class.post(path, prepare(body, headers))
|
31
|
+
parse_response
|
32
|
+
@response_body
|
33
|
+
end
|
34
|
+
|
35
|
+
def put(path, body = '', headers = {})
|
36
|
+
reset
|
37
|
+
headers = default_headers.merge(headers)
|
38
|
+
@response_body = self.class.put(path, prepare(body, headers))
|
39
|
+
parse_response
|
40
|
+
@response_body
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(path, query={}, headers = {})
|
44
|
+
reset
|
45
|
+
headers = default_headers.merge(headers)
|
46
|
+
options = {query: query, headers: headers}
|
47
|
+
@response_body = self.class.delete(path, options)
|
48
|
+
parse_response
|
49
|
+
@response_body
|
50
|
+
end
|
51
|
+
|
52
|
+
def head(path, headers = {})
|
53
|
+
reset
|
54
|
+
@response_body = self.class.head(path, prepare(nil, headers))
|
55
|
+
parse_response
|
56
|
+
@response_body
|
57
|
+
end
|
58
|
+
|
59
|
+
def base_uri=(uri = nil)
|
60
|
+
self.class.base_uri uri
|
61
|
+
end
|
62
|
+
|
63
|
+
def default_headers
|
64
|
+
header = self.class.default_options[:headers] || {}
|
65
|
+
header.merge({"Content-Type" => "application/json"})
|
66
|
+
if @session_id
|
67
|
+
header.merge!('X-SESSION_ID' => self.session_id)
|
68
|
+
end
|
69
|
+
header
|
70
|
+
end
|
71
|
+
|
72
|
+
def default_headers=(header_hash)
|
73
|
+
self.class.default_options[:headers] = header_hash
|
74
|
+
end
|
75
|
+
|
76
|
+
def session_id=(session_id)
|
77
|
+
@session_id = session_id
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
# login to commonsense
|
82
|
+
# @return [String] session_id
|
83
|
+
def login(username, password)
|
84
|
+
password = Digest::MD5.hexdigest password
|
85
|
+
post('/login.json', {:username => username, :password => password})
|
86
|
+
|
87
|
+
if @response_code == 200
|
88
|
+
self.session_id = response_body['session_id']
|
89
|
+
else
|
90
|
+
errors = [response_body['error']]
|
91
|
+
end
|
92
|
+
|
93
|
+
session_id
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def reset
|
98
|
+
@errors = nil
|
99
|
+
@response_code = nil
|
100
|
+
@response_body = nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_response
|
104
|
+
@response_code = @response_body.response.code.to_i
|
105
|
+
@response_headers = @response_body.headers
|
106
|
+
if @response_code >= 400
|
107
|
+
@errors = [response_body['error']]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def prepare(body=nil, headers={})
|
112
|
+
headers = default_headers.merge(headers)
|
113
|
+
{:body => body.to_json, :headers => headers}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|