teapi 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5138454327fd704c9c3838321b3e319230d23ee5
4
+ data.tar.gz: 7967b10da3af52773f314e5734d1ab24ec2d580a
5
+ SHA512:
6
+ metadata.gz: 87124942e3cf5e193666da26ea4987ba720202e6665b2553ab7091450e68dc3cf56719727cb7073ae90feb03ccf59649a42b1d4a2ead57d17a67af652dc80e11
7
+ data.tar.gz: e09bcec2df9e3cc355f2b78c2fc7c5b3957bb28c9d89e5dcc10352a6d887da4de21c624764eef3f8caae353dd4056be77960d2e9d9ba6985df1eb8693472b270
data/lib/teapi.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'teapi/version'
2
+ require 'teapi/configuration'
3
+ require 'teapi/documents'
4
+ require 'teapi/sender'
5
+
6
+ module Teapi #:nodoc
7
+ class << self
8
+ attr_accessor :sender
9
+ attr_writer :configuration
10
+
11
+ # Sets the configuration options.
12
+ # Teapi.configure do |config|
13
+ # config.host = 'HOST'
14
+ # config.sync_key = 'KEY'
15
+ # config.sync_secret = 'SECRET'
16
+ # end
17
+ def configure
18
+ yield(configuration)
19
+ self.sender = Sender.new(configuration)
20
+ end
21
+
22
+ # Gets the current configuration
23
+ def configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ # Issues a POST request to the teapi.io service
28
+ # @param resource [Symbol] name of resource
29
+ # @param body [Hash] to send to the service
30
+ def post(resource, body)
31
+ sender.request(:post, resource, {body: body})
32
+ end
33
+
34
+ # Issues a PUT request to the teapi.io service
35
+ # @param resource [Symbol] name of resource
36
+ # @param body [Hash] to send to the service
37
+ def put(resource, body)
38
+ sender.request(:put, resource, {body: body})
39
+ end
40
+
41
+ # Issues a DELETE request to the teapi.io service
42
+ # @param resource [Symbol] name of resource
43
+ # @param body [Hash] to send to the service
44
+ def delete(resource, body)
45
+ sender.request(:delete, resource, {body: body})
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ module Teapi
2
+ class Configuration
3
+ OPTIONS = [
4
+ :sync_key, :sync_secret, :host, :port, :secure,
5
+ :http_open_timeout, :http_read_timeout].freeze
6
+
7
+ attr_accessor :sync_key, :sync_secret, :host, :port, :secure
8
+ attr_accessor :http_open_timeout, :http_read_timeout
9
+
10
+ def initialize
11
+ @port = 443
12
+ @secure = true
13
+ @http_open_timeout = 10
14
+ @http_read_timeout = 10
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ module Teapi
2
+ # Manages documents
3
+ class Documents
4
+ # creates a new document belonging to the given type
5
+ # @param type [String] the document's type
6
+ # @param doc [Hash] document to create
7
+ def self.create(type, doc)
8
+ Teapi.post(:documents, Oj.dump({type: type, doc: doc}, mode: :compat))
9
+ end
10
+
11
+ # updates the document belonging to the given type
12
+ # @param type [String] the document's type
13
+ # @param doc [Hash] the document to update
14
+ def self.update(type, doc)
15
+ Teapi.put(:documents, Oj.dump({type: type, doc: doc}, mode: :compat))
16
+ end
17
+
18
+ # deletes the document, by its id, belonging to the given type
19
+ # @param type [String] the document's type
20
+ # @param doc [Hash] the document to update
21
+ def self.delete(type, id)
22
+ Teapi.delete(:documents, Oj.dump({type: type, id: id}, mode: :compat))
23
+ end
24
+
25
+ # bulk updates a type
26
+ # @param type [String] the document's type
27
+ # @param created_or_updated [Array[Hash]] an array of documents to be created or updated
28
+ # @param deleted [Array[Hash]] an array of document [{id: 343}, {id: 9920},...]
29
+ def self.bulk(type, created_or_updated, deleted)
30
+ return if (created_or_updated.nil? || created_or_updated.length == 0) && (deleted.nil? || deleted.length == 0)
31
+ Teapi.post(:documents, Oj.dump({type: type, deletes: deleted, upserts: created_or_updated}, mode: :compat))
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ require 'oj'
2
+ require 'uri'
3
+ require 'zlib'
4
+ require 'openssl'
5
+ require 'httparty'
6
+ require 'stringio'
7
+
8
+ module Teapi
9
+ class Sender
10
+ BASE_URL = '/v1/'
11
+ HEADERS = {'Accept' => 'application/json'}
12
+
13
+ def initialize(configuration)
14
+ @configuration = configuration
15
+ end
16
+
17
+ def request(method, resource, args = {}, ts = nil)
18
+ url = "#{BASE_URL}#{resource}?ts=#{ts || Time.now.to_i}"
19
+ args[:headers] = (args[:headers] || {}).merge({
20
+ 'Authorization' => sign(url, args),
21
+ })
22
+ if args[:body] != nil && args[:body].length > 1024 then
23
+ args[:body] = gzip(args[:body])
24
+ args[:headers]['Content-Encoding'] = 'gzip'
25
+ end
26
+ scheme = @configuration.secure ? "https" : "http"
27
+ res = HTTParty.send(method, "#{scheme}://#{@configuration.host}#{url}", args)
28
+ if res.code == 401 && res.parsed_response.include?('ts') && ts.nil?
29
+ return request(method, resource, args, res.parsed_response['ts'])
30
+ end
31
+ res
32
+ end
33
+
34
+ def sign(url, args)
35
+ data = url
36
+ data += args[:body] if args.include?(:body)
37
+ signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @configuration.sync_secret, data)
38
+ "HMAC-SHA256 Credential=#{@configuration.sync_key},Signature=#{signature}"
39
+ end
40
+
41
+ def gzip(body)
42
+ io = StringIO.new("w")
43
+ gz = Zlib::GzipWriter.new(io)
44
+ gz.write(body)
45
+ gz.close
46
+ io.string
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Teapi
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Karl Seguin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 2.11.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 2.11.1
41
+ description: ruby client for teapi.io
42
+ email:
43
+ - support@teapi.io
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/teapi.rb
49
+ - lib/teapi/configuration.rb
50
+ - lib/teapi/documents.rb
51
+ - lib/teapi/sender.rb
52
+ - lib/teapi/version.rb
53
+ homepage: http://www.teapi.io
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.4.3
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: A ruby client for teapi.io
77
+ test_files: []