r_simperium 0.2.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
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rest-client', '~> 1.6'
4
+ gem 'uuidtools', '~> 2.1'
5
+ gem 'multi_json', '~> 1.0'
6
+
7
+ group :development do
8
+ gem 'minitest', '~> 2'
9
+ gem 'turn', '~> 0.9'
10
+ gem 'rdoc', '~> 3.12'
11
+ gem 'bundler', '~> 1.1.0'
12
+ gem 'jeweler', '~> 1.8.3'
13
+ gem 'yard', '~> 0.8'
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ ansi (1.4.2)
5
+ git (1.2.5)
6
+ jeweler (1.8.3)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rdoc
11
+ json (1.7.0)
12
+ mime-types (1.18)
13
+ minitest (2.12.1)
14
+ multi_json (1.3.4)
15
+ rake (0.9.2.2)
16
+ rdoc (3.12)
17
+ json (~> 1.4)
18
+ rest-client (1.6.7)
19
+ mime-types (>= 1.16)
20
+ turn (0.9.5)
21
+ ansi
22
+ uuidtools (2.1.2)
23
+ yard (0.8.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.1.0)
30
+ jeweler (~> 1.8.3)
31
+ minitest (~> 2)
32
+ multi_json (~> 1.0)
33
+ rdoc (~> 3.12)
34
+ rest-client (~> 1.6)
35
+ turn (~> 0.9)
36
+ uuidtools (~> 2.1)
37
+ yard (~> 0.8)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Gilbert
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,19 @@
1
+ = r_simperium
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to r_simperium
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2012 Gilbert. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "r_simperium"
18
+ gem.homepage = "http://github.com/mindeavor/r_simperium"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A ruby client for Simperium}
21
+ gem.description = %Q{r_simperium aims to mimic Simperium's official python library.}
22
+ gem.email = "gilbertbgarza@gmail.com"
23
+ gem.authors = ["Gilbert"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'spec'
31
+ test.pattern = 'spec/**/{*_spec.rb,test_*.rb}'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'yard'
38
+ YARD::Rake::YardocTask.new do |t|
39
+ t.files = ['lib/**/*.rb']
40
+ t.options = [] # optional
41
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,27 @@
1
+ require 'ostruct'
2
+ require 'uuidtools'
3
+ require 'rest_client'
4
+ require 'multi_json'
5
+
6
+ module RSimperium
7
+ META_MAP = {
8
+ :x_simperium_version => :version
9
+ }
10
+
11
+ class << self
12
+ def gen_uuid(name)
13
+ UUIDTools::UUID.sha1_create(UUIDTools::UUID_OID_NAMESPACE, name)
14
+ end
15
+
16
+ def log(str)
17
+ return unless ENV['R_SIMPERIUM_DEBUG'] == '1'
18
+ puts str
19
+ end
20
+ end
21
+ end
22
+
23
+ Struct.new('ApiResponse', :meta, :data, :raw_response)
24
+
25
+ %w{api_helpers auth bucket api}.each do |file|
26
+ require File.join(File.dirname(__FILE__), 'r_simperium', file)
27
+ end
@@ -0,0 +1,22 @@
1
+ module RSimperium
2
+ class Api
3
+
4
+ # @todo Document
5
+ def initialize(app_id, auth_token, options={})
6
+ @app_id = app_id
7
+ @token = auth_token
8
+ @options = options
9
+ end
10
+
11
+ # @todo Document
12
+ def [](name)
13
+ get_item(name)
14
+ end
15
+
16
+ # @todo Document
17
+ def get_item(name)
18
+ Bucket.new(@app_id, @token, name.to_s, @options)
19
+ end
20
+
21
+ end # Api
22
+ end # Rsimperium
@@ -0,0 +1,66 @@
1
+ module RSimperium
2
+ module ApiHelpers
3
+
4
+ def api_url(path)
5
+ "#{@scheme}://#{@host}/1/#{@app_id}#{path}"
6
+ end
7
+
8
+ def api_auth_header
9
+ if @host == 'auth.simperium.com'
10
+ {'X-Simperium-API-Key' => "#{@api_key}"}
11
+ elsif @host == 'api.simperium.com'
12
+ {'X-Simperium-Token' => "#{@auth_token}"}
13
+ else
14
+ {}
15
+ end
16
+ end
17
+
18
+ def api_request(method, url, options={})
19
+ RSimperium.log "> Api Request: #{method.to_s.upcase} #{url}"
20
+ RSimperium.log " Options: #{options}"
21
+ request = options.merge(:method => method, :url => url)
22
+ request[:headers] ||= {}
23
+ request[:headers][:accept] ||= :json
24
+
25
+ request[:timeout] = -1 if options[:timeout] == false
26
+
27
+ if request[:params]
28
+ request[:params].each do |k,v|
29
+ request[:params][k] = '1' if v == true
30
+ end
31
+ # RestClient is weird, it wants the params in the headers hash
32
+ request[:headers][:params] = request[:params]
33
+ end
34
+
35
+ response = RestClient::Request.execute request
36
+ RSimperium.log ">> Response: #{response}\n\n"
37
+ begin
38
+ parsed = (response && response.length >= 2) ? MultiJson.decode(response) : response
39
+ Struct::ApiResponse.new(api_meta(response.headers), parsed, response)
40
+ rescue JSON::ParserError
41
+ Struct::ApiResponse.new(api_meta(response.headers), response.to_s, response)
42
+ end
43
+ end
44
+
45
+ def api_request_with_auth(method, url, options={})
46
+ options[:headers] ||= {}
47
+ options[:headers].merge! api_auth_header
48
+ api_request(method, url, options)
49
+ end
50
+
51
+ def api_meta(headers)
52
+ meta = {}
53
+ headers.each {|k,v|
54
+ new_key = RSimperium::META_MAP[k]
55
+ next if new_key.nil?
56
+ if v =~ /^[-+]?[0-9]+$/
57
+ meta[new_key] = v.to_i
58
+ else
59
+ meta[new_key] = v
60
+ end
61
+ }
62
+ OpenStruct.new(meta)
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,85 @@
1
+ module RSimperium
2
+
3
+ # Example use:
4
+ #
5
+ # require 'r_simperium'
6
+ # auth = RSimprium::Auth.new 'myapp', 'cbbae31841ac4d44a93cd82081a5b74f'
7
+ # access_token = auth.create 'johnny@company.com', 'secret123'
8
+ class Auth
9
+ include RSimperium::ApiHelpers
10
+
11
+ # A new Auth object that creates and authorizes Simperium users.
12
+ # @param [String] app_id Your Simperium app id
13
+ # @param [String] api_key Your Simperium app api key
14
+ # @param [String] host The host to send requests to
15
+ # @param [String] scheme The scheme to use for requests
16
+ def initialize(app_id, api_key, host=nil, scheme='https')
17
+ host ||= ENV['SIMPERIUM_AUTHHOST'] || 'auth.simperium.com'
18
+ @app_id = app_id
19
+ @api_key = api_key
20
+ @host = host
21
+ @scheme = scheme
22
+ end
23
+
24
+ # Authorizes an existing Simperium user.
25
+ # @param [String] username The user's username
26
+ # @param [String] password The user's password
27
+ # @return [String] The user's access token
28
+ def authorize(username, password)
29
+ data = {
30
+ :clientid => @api_key,
31
+ :username => username,
32
+ :password => password, }
33
+ response = api_request_with_auth :post, api_url('/authorize/'), :payload => data
34
+ response.data['access_token']
35
+ end
36
+
37
+ # Creates a new Simperium user and returns its access token.
38
+ # @param [String] username The new user's username
39
+ # @param [String] password The new user's password
40
+ # @return [String] The new user's access token
41
+ def create(username, password)
42
+ data = {
43
+ :clientid => @api_key,
44
+ :username => username,
45
+ :password => password, }
46
+ begin
47
+ response = api_request_with_auth :post, api_url('/create/'), :payload => data
48
+ response.data['access_token']
49
+ rescue RestClient::Exception => e
50
+ puts "The api request failed: #{e.message}"
51
+ nil
52
+ end
53
+ end
54
+
55
+ # Resets a Simperium user's password
56
+ # @param [String] username The user's username
57
+ # @param [String] password The user's new password (optional)
58
+ # @return [boolean] True if reset was a success
59
+ def change_password(username, new_password)
60
+ data = {
61
+ :username => username,
62
+ :new_password => new_password
63
+ }
64
+ begin
65
+ response = api_request_with_auth :post, api_url('/reset_password/'), :payload => data
66
+ return response.data['status'] == 'success'
67
+ rescue RestClient::Exception => e
68
+ puts "The api request failed: #{e.message}"
69
+ false
70
+ end
71
+ end
72
+
73
+ # Deletes a Simperium user and all user data.
74
+ # Requires an API key with admin privileges.
75
+ # @param [String] username The new user's username
76
+ def delete(username)
77
+ data = {
78
+ :clientid => @api_key,
79
+ :username => username}
80
+ api_request_with_auth :post, api_url('/delete/'), :payload => data
81
+ end
82
+
83
+ end # Auth
84
+ end # RSimperium
85
+
@@ -0,0 +1,188 @@
1
+
2
+
3
+ module RSimperium
4
+
5
+ # Example use:
6
+ #
7
+ # require 'r_simperium'
8
+ # bucket = RSimperium::Bucket.new('myapp', 'db3d2a64abf711e0b63012313d001a3b', 'mybucket')
9
+ # bucket.set 'item2', :age => 23
10
+ # # => True
11
+ # bucket.set 'item2', :age => 25
12
+ # # => True
13
+ # bucket.get 'item2'
14
+ # # => {'age' => 25}
15
+ # bucket.get 'item2', :version => 1
16
+ # # => {'age' => 23}
17
+ class Bucket
18
+ include RSimperium::ApiHelpers
19
+
20
+ # A new Bucket object to interact with Simperium data.
21
+ #
22
+ # @overload initialize(app_id, auth_token, bucket, opts={})
23
+ # @param [String] app_id Your Simperium app id
24
+ # @param [String] auth_token A user's Simperium auth token
25
+ # @param [String] bucket The name of the bucket to interact with
26
+ # @option opts [String] :userid The
27
+ # @option opts [String] :host ('api.simperium.com') The host to send requests to
28
+ # @option opts [String] :scheme ('https') The scheme to use for requests
29
+ # @option opts [String] :clientid (a new uuid) A specific clientid to use
30
+ def initialize(app_id, auth_token, bucket, opts={})
31
+ @app_id = app_id
32
+ @bucket = bucket
33
+ @auth_token = auth_token
34
+
35
+ @userid = opts[:userid]
36
+ @host = opts[:host] || ENV['SIMPERIUM_APIHOST'] || 'api.simperium.com'
37
+ @scheme = opts[:scheme] || 'https'
38
+ @clientid = opts[:clientid] || "py-#{RSimperium.gen_uuid @app_id}"
39
+ end
40
+
41
+ # Retrieve a page of the latest versions of a buckets documents
42
+ # ordered by most the most recently modified.
43
+ #
44
+ # @option params [String] :mark mark the documents returned to be modified after the
45
+ # given cv
46
+ # @option params [String] :limit limit page size to this number. max 1000, default 100.
47
+ # @option params [String] :since limit page to documents changed since the given cv.
48
+ # @option params [String] :data include the current data state of each document in the
49
+ # result. by default data is not included.
50
+ #
51
+ # @return [Hash, string keys] See {https://simperium.com/docs/reference/http Simperium's api page}
52
+ # for the values inside the returned hash.
53
+ def index(params={})
54
+ api_request_with_auth :get, api_url("/#{@bucket}/index"), :params => params
55
+ end
56
+
57
+ # Retrieves either the latest version of item from this bucket, or the
58
+ # specific version requested
59
+ #
60
+ # @param item_id [String] The item to retrieve
61
+ # @option opts [String] :version The version of the item to retrieve
62
+ # @option opts [String] :default A hash to return if the item does not exist
63
+ def get(item_id, opts={})
64
+ path = "/#{@bucket}/i/#{item_id}"
65
+ path += "/v/#{opts[:version]}" if opts[:version]
66
+ begin
67
+ api_request_with_auth :get, api_url(path)
68
+ rescue RestClient::ResourceNotFound
69
+ opts[:default]
70
+ end
71
+ end
72
+
73
+ # Posts the supplied data to item.
74
+ #
75
+ # @param item_id [String] The item to retrieve
76
+ # @param data [Hash] A hash of data to be json-encoded
77
+ # @option opts [String] :version The version of the item to retrieve
78
+ # @option opts [String] :default A hash to return if the item does not exist
79
+ # @option opts [String] :ccid A unique id for this change. If you need to resubmit
80
+ # this operation, you should send the same ccid to prevent duplicate operations.
81
+ # @option opts [Boolean] :response If true, the item will be included in the response
82
+ #
83
+ # @return [String] if a unique change id on success, or nil, if the post was not
84
+ # successful
85
+ #
86
+ def post(item_id, data, opts={})
87
+ path = "/#{@bucket}/i/#{item_id}"
88
+ path += "/v/#{opts[:version]}" if opts[:version]
89
+
90
+ opts[:ccid] || RSimperium.gen_uuid(@app_id)
91
+ opts[:clientid] = @clientid
92
+ data = MultiJson.encode(data)
93
+
94
+ begin
95
+ response = api_request_with_auth :post, api_url(path), :payload => data,
96
+ :params => opts
97
+ rescue RestClient::Exception => e
98
+ return nil
99
+ end
100
+ end
101
+
102
+ # @todo Document
103
+ def new(data, ccid=nil)
104
+ self.post RSimperium.gen_uuid(@app_id), data, :ccid => ccid
105
+ end
106
+
107
+ # @todo Document
108
+ def set(item_id, data, options={})
109
+ self.post(item_id, data, options)
110
+ end
111
+
112
+ # @todo Document
113
+ # deletes the item from bucket
114
+ def delete(item_id, version=nil)
115
+ path = "/#{@bucket}/i/#{item_id}"
116
+
117
+ ccid = RSimperium.gen_uuid(@app_id)
118
+ params = {
119
+ :version => version,
120
+ :clientid => @clientid,
121
+ :ccid => ccid
122
+ }
123
+
124
+ api_request_with_auth :delete, api_url(path), :params => params
125
+ end
126
+
127
+ # @todo Document
128
+ # retrieves updates for this bucket for this user
129
+ #
130
+ # @cv: if supplied only updates that occurred after this
131
+ # change version are retrieved.
132
+ #
133
+ # @timeout: the call will wait for updates if not are immediately
134
+ # available. by default it will wait indefinately. if a timeout
135
+ # is supplied an empty list will be return if no updates are made
136
+ # before the timeout is reached.
137
+ #
138
+ def changes(params={})
139
+ # cv=nil, timeout=nil
140
+ path = "/#{@bucket}/changes?clientid=#{@clientid}"
141
+ params[:clientid] = @clientid
142
+
143
+ begin
144
+ api_request_with_auth :get, api_url(path), :params => params
145
+ rescue RestClient::Exception => e
146
+ return [] if e.http_code == 504 || e.message =~ /(timed out|Connection refused)/
147
+ raise
148
+ end
149
+ end
150
+
151
+ # @todo Document
152
+ # retrieves *all* updates for this bucket, regardless of the user
153
+ # which made the update.
154
+ #
155
+ # @cv: if supplied only updates that occurred after this
156
+ # change version are retrieved.
157
+ #
158
+ # @data: if True, also include the lastest version of the data for
159
+ # changed entity
160
+ #
161
+ # @username: if True, also include the username that created the
162
+ # change
163
+ #
164
+ # @most_recent: if True, then only the most recent change for each
165
+ # document in the current page will be returned. e.g. if a
166
+ # document has been recently changed 3 times, only the latest of
167
+ # those 3 changes will be returned.
168
+ #
169
+ # @timeout: the call will wait for updates if not are immediately
170
+ # available. by default it will wait indefinately. if a timeout
171
+ # is supplied an empty list will be return if no updates are made
172
+ # before the timeout is reached.
173
+ #
174
+ def all(params={})
175
+ # cv=nil, data=false, username=false, most_recent=false, timeout=nil
176
+ path = "/#{@bucket}/all"
177
+ params[:clientid] = @clientid
178
+
179
+ begin
180
+ api_request_with_auth :get, api_url(path), :params => params
181
+ rescue RestClient::Exception => e
182
+ return [] if e.http_code == 504 || e.message =~ /(timed out|Connection refused)/
183
+ raise
184
+ end
185
+ end
186
+
187
+ end # Bucket
188
+ end # RSimperium
@@ -0,0 +1,11 @@
1
+ class ChangeProcessor
2
+
3
+ def process(change)
4
+ if change['o'] == 'M' && change.include?('sv')
5
+ change['v'].each do |key|
6
+ handler = :"on_change_#{key}"
7
+ self.send handler, change['d'][key] if self.respond_to?(handler)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,82 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "r_simperium"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Gilbert"]
12
+ s.date = "2012-08-03"
13
+ s.description = "r_simperium aims to mimic Simperium's official python library."
14
+ s.email = "gilbertbgarza@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/r_simperium.rb",
28
+ "lib/r_simperium/api.rb",
29
+ "lib/r_simperium/api_helpers.rb",
30
+ "lib/r_simperium/auth.rb",
31
+ "lib/r_simperium/bucket.rb",
32
+ "lib/r_simperium/changes.rb",
33
+ "r_simperium.gemspec",
34
+ "spec/core_helper.rb",
35
+ "spec/spec_helper.rb",
36
+ "spec/test_api.rb",
37
+ "spec/test_auth.rb",
38
+ "spec/test_bucket.rb"
39
+ ]
40
+ s.homepage = "http://github.com/mindeavor/r_simperium"
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = "1.8.21"
44
+ s.summary = "A ruby client for Simperium"
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<rest-client>, ["~> 1.6"])
51
+ s.add_runtime_dependency(%q<uuidtools>, ["~> 2.1"])
52
+ s.add_runtime_dependency(%q<multi_json>, ["~> 1.0"])
53
+ s.add_development_dependency(%q<minitest>, ["~> 2"])
54
+ s.add_development_dependency(%q<turn>, ["~> 0.9"])
55
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
56
+ s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
57
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
58
+ s.add_development_dependency(%q<yard>, ["~> 0.8"])
59
+ else
60
+ s.add_dependency(%q<rest-client>, ["~> 1.6"])
61
+ s.add_dependency(%q<uuidtools>, ["~> 2.1"])
62
+ s.add_dependency(%q<multi_json>, ["~> 1.0"])
63
+ s.add_dependency(%q<minitest>, ["~> 2"])
64
+ s.add_dependency(%q<turn>, ["~> 0.9"])
65
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
66
+ s.add_dependency(%q<bundler>, ["~> 1.1.0"])
67
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
68
+ s.add_dependency(%q<yard>, ["~> 0.8"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<rest-client>, ["~> 1.6"])
72
+ s.add_dependency(%q<uuidtools>, ["~> 2.1"])
73
+ s.add_dependency(%q<multi_json>, ["~> 1.0"])
74
+ s.add_dependency(%q<minitest>, ["~> 2"])
75
+ s.add_dependency(%q<turn>, ["~> 0.9"])
76
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
77
+ s.add_dependency(%q<bundler>, ["~> 1.1.0"])
78
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
79
+ s.add_dependency(%q<yard>, ["~> 0.8"])
80
+ end
81
+ end
82
+
@@ -0,0 +1,14 @@
1
+
2
+ class TestCore < MiniTest::Unit::TestCase
3
+
4
+ def setup
5
+ @api_key = ENV['SIMPERIUM_CLIENT_TEST_API_KEY']
6
+ @app_id = ENV['SIMPERIUM_CLIENT_TEST_APP_ID']
7
+ @admin_api_key = ENV['SIMPERIUM_CLIENT_TEST_ADMIN_APP_ID']
8
+
9
+ assert @api_key.nil? == false, 'please set SIMPERIUM_CLIENT_TEST_APIKEY'
10
+ assert @app_id.nil? == false, 'please set SIMPERIUM_CLIENT_TEST_APPID'
11
+ assert @admin_api_key.nil? == false, 'please set SIMPERIUM_CLIENT_TEST_ADMIN_APPID'
12
+ end
13
+
14
+ end
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'turn/autorun'
11
+ require 'minitest/spec'
12
+ require 'minitest/unit'
13
+
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
16
+ require 'r_simperium'
17
+
18
+
19
+ def gen_uuid
20
+ UUIDTools::UUID.timestamp_create.hexdigest
21
+ end
22
+
23
+ @_auth_token = nil
24
+ def get_auth_token(return_creds=false)
25
+ if @_auth_token.nil?
26
+ auth = RSimperium::Auth.new(@app_id, @api_key)
27
+ username = gen_uuid + '@foo.com'
28
+ password = gen_uuid
29
+ @_auth_token = auth.create(username, password)
30
+ end
31
+
32
+ if return_creds
33
+ [@_auth_token, username, password]
34
+ else
35
+ @_auth_token
36
+ end
37
+ end
38
+
39
+ # Monkey patch (just for testing!)
40
+ class Hash
41
+ def stringify_keys!
42
+ keys.each do |key|
43
+ self[key.to_s] = delete(key)
44
+ end
45
+ self
46
+ end
47
+ end
data/spec/test_api.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'core_helper'
3
+
4
+ class TestApi < TestCore
5
+ def test_getitem
6
+ api = RSimperium::Api.new(@app_id, get_auth_token)
7
+ assert_equal true, api[:random_bucket].is_a?(RSimperium::Bucket)
8
+ end
9
+ end
data/spec/test_auth.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'core_helper'
3
+
4
+ class TestAuth < TestCore
5
+ def test_create
6
+ refute_nil get_auth_token
7
+ end
8
+
9
+ def test_delete
10
+ token, username, pass = get_auth_token(true)
11
+ auth = RSimperium::Auth.new(@app_id, @admin_api_key)
12
+ assert_equal 200, auth.delete(username).raw_response.code
13
+ end
14
+
15
+ def test_change_password
16
+ token, username, pass = get_auth_token(true)
17
+
18
+ admin_auth = RSimperium::Auth.new(@app_id, @admin_api_key)
19
+ new_pass = gen_uuid
20
+ assert_equal true, admin_auth.change_password(username, new_pass)
21
+
22
+ # An admin key cannot authorize a user
23
+ auth = RSimperium::Auth.new(@app_id, @api_key)
24
+ assert_equal false, auth.authorize(username, new_pass).nil?
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'core_helper'
3
+
4
+ class TestBucket < TestCore
5
+ def test_get
6
+ bucket = RSimperium::Bucket.new(@app_id, get_auth_token, gen_uuid)
7
+ bucket.post('item1', 'x' => 1)
8
+ assert_equal({'x' => 1}, bucket.get('item1').data)
9
+ end
10
+
11
+ def test_index
12
+ bucket = RSimperium::Bucket.new(@app_id, get_auth_token, gen_uuid)
13
+ 3.times {|i| bucket.post "item#{i}", 'x' => i}
14
+
15
+ got = bucket.index(:limit => 2).data
16
+ want = {
17
+ :current => got['current'],
18
+ :mark => got['mark'],
19
+ :index => [
20
+ # Index items should be ordered with most recently modified first
21
+ {:id => 'item2', :v => 1}.stringify_keys!,
22
+ {:id => 'item1', :v => 1}.stringify_keys!,
23
+ ],
24
+ }.stringify_keys!
25
+
26
+ assert_equal want, got
27
+
28
+ got2 = bucket.index(:limit => 2, :mark => got['mark']).data
29
+ want2 = {
30
+ :current => got['current'],
31
+ :index => [
32
+ {:id => 'item0', :v => 1}.stringify_keys!
33
+ ],
34
+ }.stringify_keys!
35
+
36
+ assert_equal want, got
37
+ end
38
+
39
+ def test_post
40
+ bucket = RSimperium::Bucket.new(@app_id, get_auth_token, gen_uuid)
41
+ response = bucket.post 'item-1', { :x => 1 }
42
+ assert_equal 1, response.meta.version
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,213 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: r_simperium
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gilbert
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.6'
30
+ - !ruby/object:Gem::Dependency
31
+ name: uuidtools
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.1'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.1'
46
+ - !ruby/object:Gem::Dependency
47
+ name: multi_json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2'
78
+ - !ruby/object:Gem::Dependency
79
+ name: turn
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.9'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.9'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rdoc
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '3.12'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '3.12'
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.1.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.1.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: jeweler
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.8.3
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 1.8.3
142
+ - !ruby/object:Gem::Dependency
143
+ name: yard
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '0.8'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '0.8'
158
+ description: r_simperium aims to mimic Simperium's official python library.
159
+ email: gilbertbgarza@gmail.com
160
+ executables: []
161
+ extensions: []
162
+ extra_rdoc_files:
163
+ - LICENSE.txt
164
+ - README.rdoc
165
+ files:
166
+ - .document
167
+ - Gemfile
168
+ - Gemfile.lock
169
+ - LICENSE.txt
170
+ - README.rdoc
171
+ - Rakefile
172
+ - VERSION
173
+ - lib/r_simperium.rb
174
+ - lib/r_simperium/api.rb
175
+ - lib/r_simperium/api_helpers.rb
176
+ - lib/r_simperium/auth.rb
177
+ - lib/r_simperium/bucket.rb
178
+ - lib/r_simperium/changes.rb
179
+ - r_simperium.gemspec
180
+ - spec/core_helper.rb
181
+ - spec/spec_helper.rb
182
+ - spec/test_api.rb
183
+ - spec/test_auth.rb
184
+ - spec/test_bucket.rb
185
+ homepage: http://github.com/mindeavor/r_simperium
186
+ licenses:
187
+ - MIT
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ segments:
199
+ - 0
200
+ hash: 510951770569022528
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ none: false
203
+ requirements:
204
+ - - ! '>='
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ requirements: []
208
+ rubyforge_project:
209
+ rubygems_version: 1.8.21
210
+ signing_key:
211
+ specification_version: 3
212
+ summary: A ruby client for Simperium
213
+ test_files: []