backchat-client 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --colour
3
+ --tty
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in backchat-client.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Juan de Bravo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ This is a light library to access the Backchat provisioning API
2
+
3
+ # Installation
4
+
5
+ gem install backchat-client
6
+
7
+ # Current version
8
+
9
+ 0.1
10
+
11
+ # Getting started
12
+
13
+ You need a valid api-key to access Backchat API
14
+
15
+ require 'backchat-client'
16
+ bc = Backchat::Client.new("api-key")
17
+
18
+ # User Management
19
+
20
+ ## Get user profile
21
+
22
+ require 'backchat-client'
23
+ bc = Backchat::Client.new("api-key")
24
+ bc.get_profile
25
+
26
+ ## Delete user
27
+
28
+ require 'backchat-client'
29
+ bc = Backchat::Client.new("api-key")
30
+ bc.delete_user
31
+
32
+ # Streams
33
+
34
+ ## Create a new stream
35
+
36
+ require 'backchat-client'
37
+ bc = Backchat::Client.new("api-key")
38
+ bc.create_stream("stream-name")
39
+
40
+ ## Retrieve application streams
41
+
42
+ require 'backchat-client'
43
+ bc = Backchat::Client.new("api-key")
44
+
45
+ # get all streams
46
+ streams = bc.find_stream
47
+
48
+ # get a specific stream
49
+ stream = bc.find_stream("stream-name")
50
+
51
+ ## Delete a stream
52
+
53
+ require 'backchat-client'
54
+ bc = Backchat::Client.new("api-key")
55
+ bc.destroy_stream("stream-name")
56
+
57
+ # Channels
58
+
59
+ ## Create a new channel
60
+
61
+ require 'backchat-client'
62
+ bc = Backchat::Client.new("api-key")
63
+ bc.create_channel("twitter", "juandebravo")
64
+
65
+ ## Retrieve application channels
66
+
67
+ require 'backchat-client'
68
+ bc = Backchat::Client.new("api-key")
69
+
70
+ # get all channels
71
+ streams = bc.find_channel
72
+
73
+ ## Delete a channel
74
+
75
+ require 'backchat-client'
76
+ bc = Backchat::Client.new("api-key")
77
+ bc.destroy_channel("twitter://juandebravo")
78
+
79
+ # License
80
+
81
+ The MIT License
82
+
83
+ Copyright (c) 2011 Juan de Bravo, Alberto Pastor, Rafael de Oleza.
84
+
85
+ Permission is hereby granted, free of charge, to any person obtaining a copy
86
+ of this software and associated documentation files (the "Software"), to deal
87
+ in the Software without restriction, including without limitation the rights
88
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
89
+ copies of the Software, and to permit persons to whom the Software is
90
+ furnished to do so, subject to the following conditions:
91
+
92
+ The above copyright notice and this permission notice shall be included in
93
+ all copies or substantial portions of the Software.
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
96
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
97
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
98
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
99
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
100
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
101
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :default => [:test]
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:test) do |spec|
8
+ spec.skip_bundler = true
9
+ spec.pattern = 'spec/*_spec.rb'
10
+ spec.rspec_opts = '--color --format doc'
11
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "backchat_client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "backchat-client"
7
+ s.version = BackchatClient::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["This gem provides an easy way to access Backchat provisioning API"]
10
+ s.email = ["juandebravo@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Gem to access Backchat provisioning API}
13
+ s.description = %q{Gem to access Backchat provisioning API using rest_client as http client}
14
+
15
+ s.rubyforge_project = "backchat-client"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency("rest-client")
23
+ s.add_dependency("activesupport")
24
+ s.add_dependency("addressable")
25
+ s.add_development_dependency('rspec')
26
+ s.add_development_dependency('webmock')
27
+ end
@@ -0,0 +1,23 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 3 and
6
+ (
7
+ puts "Please include as argument the api_key, the origin stream slug and the new channel to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+ stream_slug = ARGV.shift
13
+ channel = ARGV.shift
14
+
15
+ bc = Backchat::Client.new(api_key)
16
+ bc.logger.level = Logger::DEBUG
17
+
18
+ begin
19
+ puts bc.set_channels(stream_slug, [{:channel => channel}])
20
+ rescue Exception => ex
21
+ puts ex
22
+ puts ex.inspect
23
+ end
@@ -0,0 +1,20 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 2 and
6
+ (
7
+ puts "Please include as argument the api_key, channel_type and channel_name to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ type = ARGV.shift
14
+
15
+ name = ARGV.shift
16
+
17
+ bc = Backchat::Client.new(api_key)
18
+ bc.logger.level = Logger::DEBUG
19
+
20
+ puts bc.create_channel(type, name)
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 2 and
6
+ (
7
+ puts "Please include as argument the api_key and stream_name to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ stream = ARGV.shift
14
+
15
+ bc = Backchat::Client.new(api_key)
16
+ bc.logger.level = Logger::DEBUG
17
+
18
+ puts bc.create_stream(stream)
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 2 and
6
+ (
7
+ puts "Please include as argument the api_key, channel_name to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ channel = ARGV.shift
14
+
15
+ bc = Backchat::Client.new(api_key)
16
+ bc.logger.level = Logger::DEBUG
17
+
18
+ puts bc.destroy_channel(channel, true)
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 2 and
6
+ (
7
+ puts "Please include as argument the api_key, stream_name to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ stream = ARGV.shift
14
+
15
+ bc = Backchat::Client.new(api_key)
16
+ bc.logger.level = Logger::DEBUG
17
+
18
+ puts bc.destroy_stream(stream)
@@ -0,0 +1,19 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 1 and
6
+ (
7
+ puts "Please include as argument the api_key to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ bc = Backchat::Client.new(api_key)
14
+
15
+ bc.logger.level = Logger::DEBUG
16
+
17
+ puts bc.delete_user
18
+
19
+
@@ -0,0 +1,22 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 1 and
6
+ (
7
+ puts "Please include as argument the api_key"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ bc = Backchat::Client.new(api_key)
14
+ bc.logger.level=Logger::DEBUG
15
+
16
+ begin
17
+ puts bc.find_channel
18
+ rescue Exception => ex
19
+ puts ex.message
20
+ puts ex
21
+ end
22
+
@@ -0,0 +1,29 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 1 and
6
+ (
7
+ puts "Please include as argument the api_key to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+ stream = if ARGV.length < 1
14
+ ""
15
+ else
16
+ ARGV.shift
17
+ end
18
+
19
+ Backchat::Client.log_level=Logger::DEBUG
20
+ bc = Backchat::Client.new(api_key)
21
+
22
+ begin
23
+ puts bc.find_stream(stream)
24
+ rescue Exception => ex
25
+ puts ex.message
26
+ puts ex
27
+ end
28
+
29
+
data/examples/user.rb ADDED
@@ -0,0 +1,16 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'backchat-client'
4
+
5
+ ARGV.length < 1 and
6
+ (
7
+ puts "Please include as argument the api_key to be used"
8
+ exit
9
+ )
10
+
11
+ api_key = ARGV.shift
12
+
13
+
14
+ bc = Backchat::Client.new(api_key)
15
+ puts bc.get_profile
16
+
@@ -0,0 +1,212 @@
1
+ require 'backchat_client/channel'
2
+ require 'backchat_client/stream'
3
+ require 'backchat_client/user'
4
+ require 'backchat_client/backchat_logger'
5
+ require 'addressable/uri'
6
+
7
+ module Backchat
8
+
9
+ include BackchatClient::BackchatLogger
10
+
11
+ #
12
+ # This class is the main entry point to use the backchat-client gem.
13
+ # It creates a client with a specific api_key that connects to Backchat
14
+ # and processes any request.
15
+ #
16
+ class Client
17
+ include BackchatClient::BackchatLogger
18
+
19
+ # default endpoint where Backchat is deployed
20
+ DEFAULT_ENDPOINT = "https://api.backchat.io/1"
21
+
22
+ attr_accessor :api_key
23
+ attr_reader :endpoint
24
+
25
+ #
26
+ # @param *api_key* application identifier
27
+ # @param *endpoint* Backchat endpoint
28
+ #
29
+ def initialize(api_key, endpoint = nil)
30
+ @api_key = api_key
31
+ @endpoint = endpoint.nil? ? DEFAULT_ENDPOINT : endpoint
32
+ end
33
+
34
+ #
35
+ # Checks if a Token is valid
36
+ # @return true|false
37
+ #
38
+ def valid?
39
+ !get_profile.nil?
40
+ end
41
+
42
+ #
43
+ # *User management*
44
+
45
+ #
46
+ # get user profile.
47
+ # The api_key used should be associated to a user
48
+ # @return user profile or nil if invalid api_key
49
+ #
50
+ def get_profile
51
+ user.find
52
+ end
53
+
54
+ #
55
+ # Delete user account
56
+ #
57
+ def delete_user
58
+ user.destroy
59
+ end
60
+
61
+ # *Channels management*
62
+
63
+ #
64
+ # Retrieves a specific channel or all the channels associated to the api_key
65
+ # @return one or more channel data
66
+ #
67
+ def find_channel
68
+ channels = channel.find
69
+
70
+ # check that the data has the expected format
71
+ if channels.respond_to?("has_key?") and channels.has_key?("data")
72
+ channels["data"]
73
+ else
74
+ logger.info("Unable to find channels")
75
+ nil
76
+ end
77
+ end
78
+
79
+ #
80
+ # Creates a specific channel
81
+ # @param channel_type kind of channel: check Backchat documentation about supported channel types
82
+ # @param id channel unique identifier (in user scope)
83
+ #
84
+ def create_channel(channel_type, id, bql=nil)
85
+ _channel = channel.create(generate_channel_url(channel_type, id, bql))
86
+
87
+ if _channel.respond_to?("has_key?") and _channel.has_key?("data")
88
+ _channel["data"]
89
+ else
90
+ logger.error("Invalid data received while creating channel #{_channel}")
91
+ raise "No data received from Backchat while creating channel"
92
+ end
93
+ end
94
+
95
+ #
96
+ # Delete a channel
97
+ # @param *name*
98
+ # @param *force* true|false if channel should be deleted even if being used in a stream
99
+ #
100
+ def destroy_channel(name, force = false)
101
+ channel.destroy(name, force)
102
+ end
103
+
104
+ # Streams management
105
+
106
+
107
+ #
108
+ # Retrieves a specific stream
109
+ # @param *name* (optional) stream name. If undefined, all the user streams are retrieved
110
+ # @return stream data hash
111
+ #
112
+ def find_stream(name = nil)
113
+ streams = stream.find(name)
114
+
115
+ if !streams.nil? and streams.respond_to?("has_key?") and streams.has_key?("data")
116
+ streams["data"]
117
+ else
118
+ logger.debug "Stream with name #{name} not found in backchat"
119
+ nil
120
+ end
121
+ end
122
+
123
+ #
124
+ # Create a specific stream
125
+ # @param *name* unique stream identifier
126
+ # @param *description* (optional)
127
+ # @param *filters* (optional) array of filters
128
+ #
129
+ def create_stream(name, description = nil, filters = [])
130
+ description.nil? and description = "Stream created using backchat-client gem"
131
+ _stream = stream.create(name, description, filters)
132
+
133
+ if _stream.respond_to?("has_key?") and _stream.has_key?("data")
134
+ _stream["data"]
135
+ else
136
+ logger.error("Invalid data received while creating stream: #{_stream}")
137
+ raise "No data received from Backchat while creating stream"
138
+ end
139
+ end
140
+
141
+ #
142
+ # This method updates the stream, assigning the new channels array to it.
143
+ # In order to simplify, all the channels received will be automatically enabled.
144
+ # @param stream_slug stream name
145
+ # @param channels array of channels to be included in the stream
146
+ # @param reset the channels are added (false) to the current channels or remove (true) the previous ones
147
+ # @param filter valid Lucene syntax to filter the channels
148
+ # @return true if the stream was successfully updated
149
+ # @raise exception if stream is not found
150
+ #
151
+ def set_channels(stream_slug, channels = [], reset = false, filter = nil)
152
+ st = stream.find(stream_slug) or raise "stream does not exist"
153
+
154
+ st = st["data"]
155
+ # format the channels array
156
+ channels.map { |channel|
157
+ channel[:enabled] = true
158
+ channel[:channel]+="?q=#{filter}" unless filter.nil?
159
+ channel[:channel] = Addressable::URI.parse(channel[:channel]).normalize.to_s
160
+ }
161
+
162
+ if reset
163
+ # reset the stream channels
164
+ st["channel_filters"] = channels
165
+ else
166
+ # add the new channels to the existing ones
167
+ st["channel_filters"] |= channels
168
+ end
169
+
170
+ stream.update(stream_slug, st)
171
+ true
172
+ end
173
+
174
+ #
175
+ # Delete a stream
176
+ #
177
+ def destroy_stream(name)
178
+ stream.destroy(name)
179
+ end
180
+
181
+ #
182
+ # Helper that generates the channel url using Addressable help
183
+ #
184
+ def generate_channel_url(type, id, filter = nil)
185
+ channel_uri = "#{type}://#{id}"
186
+ if filter
187
+ channel_uri += "?q=#{filter}"
188
+ end
189
+ Addressable::URI.parse(channel_uri).normalize.to_s
190
+ end
191
+
192
+ private
193
+
194
+ # Composition pattern
195
+
196
+ # user management object
197
+ def user
198
+ @user ||= BackchatClient::User.new(api_key, endpoint.dup)
199
+ end
200
+
201
+ # channel management object
202
+ def channel
203
+ @channel ||= BackchatClient::Channel.new(api_key, endpoint.dup)
204
+ end
205
+
206
+ # stream management object
207
+ def stream
208
+ @stream ||= BackchatClient::Stream.new(api_key, endpoint.dup)
209
+ end
210
+
211
+ end
212
+ end
@@ -0,0 +1,75 @@
1
+ require 'logger'
2
+
3
+ module BackchatClient
4
+
5
+ #
6
+ # This module injects methods to handle log mechanism
7
+ #
8
+ module BackchatLogger
9
+ #
10
+ # Nice way to include the Module methods when including it in a class/module
11
+ #
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+
16
+ #
17
+ # This module acts as a wrapper to include the class/module level methods
18
+ #
19
+ module ClassMethods
20
+
21
+ # logger setter
22
+ # @param value should be a valid IO object (STDOUT, string representing a valid filename, File object)
23
+ # @return new Logger object created
24
+ def logger=(value)
25
+ # _logger must be static var and not class var to be shared between objects/classes
26
+ if value.is_a?(String)
27
+ @@_logger = Logger.new(value)
28
+ else
29
+ @@_logger = value
30
+ end
31
+ end
32
+
33
+ # logger getter
34
+ # @return Logger object
35
+ def logger
36
+ @@_logger ||= create_logger
37
+ end
38
+
39
+ #change logger level
40
+ # @param level valid Logger level constant (Logger::DEBUG, etc)
41
+ def log_level=(level)
42
+ logger.level = level
43
+ end
44
+
45
+ #
46
+ # Creates a new Logger object and defines the level and format
47
+ #
48
+ def create_logger(output = nil)
49
+ output.nil? and output = STDOUT
50
+ logger = Logger.new(output)
51
+ logger.level = Logger::ERROR
52
+ #logger.formatter = proc { |severity, datetime, progname, msg|
53
+ # "#{severity} on #{datetime} at #{progname}: #{msg}\n"
54
+ #}
55
+ logger.datetime_format = "%Y-%m-%d %H:%M:%S"
56
+ logger
57
+ end
58
+ end
59
+
60
+ def logger
61
+ self.class.logger
62
+ end
63
+
64
+ # debug message with the class name a the beginning of the log
65
+ def debug(message)
66
+ logger.debug "#{self.class} #{message}"
67
+ end
68
+
69
+ # error message with the class name a the beginning of the log
70
+ def error(message)
71
+ logger.error "#{self.class} #{message}"
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,61 @@
1
+ require 'backchat_client/http_client'
2
+ require 'active_support'
3
+ require 'backchat_client/backchat_logger'
4
+
5
+ module BackchatClient
6
+
7
+ #
8
+ # A Backchat Channel allows to define an external resource to fetch events using Backchat infrastructure
9
+ #
10
+ class Channel
11
+ include BackchatClient::HttpClient
12
+ include BackchatClient::BackchatLogger
13
+
14
+ # http uri to handle channels
15
+ URI_PATH = "channels"
16
+
17
+ #
18
+ # @param *api_key* application identifier
19
+ # @param *endpoint* Backchat endpoint
20
+ #
21
+ def initialize(api_key, endpoint)
22
+ @api_key = api_key
23
+ @endpoint = endpoint
24
+ end
25
+
26
+ #
27
+ # This method POST a request to create a new channel on behalf of the
28
+ # authenticated application
29
+ # @param uri valid Backchat URI, i.e. twitter://username
30
+ # @return response body
31
+ #
32
+ def create(uri)
33
+ ActiveSupport::JSON.decode(post("index.json", {:channel => uri}))
34
+ end
35
+
36
+ #
37
+ # This method sends a GET request to retrieve all the user channels
38
+ # There is no way to retrieve a specific channel
39
+ # @return response body
40
+ #
41
+ def find
42
+ ActiveSupport::JSON.decode(get("index.json"))
43
+ end
44
+
45
+ #
46
+ # Delete an application channel
47
+ # @param *name* valid channel URI
48
+ # @param *force* delete even if it is being used by a stream
49
+ # @return true|false
50
+ #
51
+ def destroy(name, force = false)
52
+ begin
53
+ ActiveSupport::JSON.decode(delete("", {:channel => name, :force => force}))
54
+ return true
55
+ rescue RestClient::ResourceNotFound
56
+ return false
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,76 @@
1
+ require 'rest_client'
2
+ require 'backchat_client/backchat_logger'
3
+
4
+ module BackchatClient
5
+ #
6
+ # This module sends HTTP requests to Backchat including the specific
7
+ # header authenticating the sender
8
+ # It's just a mixin, some features must be pre-loaded in the entity that uses
9
+ # the mixin
10
+ # @endpoint: Backchat API URI: https://api.backchat.io
11
+ # @api_key: application api key: kljdfjrwerwlkdfjsldkf
12
+ # URI_PATH: entity/model specific: streams, channels, etc.
13
+ #
14
+ module HttpClient
15
+
16
+ include BackchatClient::BackchatLogger
17
+
18
+ # HTTP GET
19
+ def get(path, params = {}, headers = {})
20
+ headers.merge!({:Authorization => "Backchat #{@api_key}", :Accept => "application/json"})
21
+
22
+ uri = set_path(path)
23
+ uri = "#{uri}?".concat(params.collect { |k, v| "#{k}=#{v.to_s}" }.join("&"))
24
+ debug("get request to uri #{uri}")
25
+ RestClient.get(uri, headers)
26
+ end
27
+
28
+ # HTTP POST
29
+ def post(path, body = {}, headers = {})
30
+ headers.merge!({:Authorization => "Backchat #{@api_key}", :content_type => :json, :accept => :json})
31
+ body = ActiveSupport::JSON.encode(body)
32
+ uri = set_path(path)
33
+ debug("post request to uri #{uri}")
34
+ debug("post body: <#{body}>")
35
+ RestClient.post("#{uri}", body, headers)
36
+ end
37
+
38
+ # HTTP PUT
39
+ def put(path, body = {}, headers = {})
40
+ headers.merge!({:Authorization => "Backchat #{@api_key}", :content_type => :json, :accept => :json})
41
+ body = ActiveSupport::JSON.encode(body)
42
+ uri = set_path(path)
43
+ debug("put request to uri #{uri}")
44
+ debug("put body: <#{body}>")
45
+ RestClient.put("#{uri}", body, headers)
46
+ end
47
+
48
+ # HTTP DELETE
49
+ def delete(path, params = {}, headers = {})
50
+ headers.merge!({:Authorization => "Backchat #{@api_key}", :accept => :json})
51
+ uri = set_path(path)
52
+ uri = "#{uri}?".concat(params.collect { |k, v| "#{k}=#{v.to_s}" }.join("&"))
53
+ debug("delete request to uri #{uri}")
54
+ RestClient.delete(uri, headers)
55
+ end
56
+
57
+ private
58
+
59
+ def set_path(path)
60
+ if uri_path.nil?
61
+ "#{@endpoint}/#{path}"
62
+ else
63
+ "#{@endpoint}/#{uri_path}/#{path}"
64
+ end
65
+ end
66
+
67
+ # Returns the entity URI_PATH constant (loaded from the entity class)
68
+ def uri_path
69
+ unless defined? self.class::URI_PATH
70
+ raise RuntimeError.new "URI_PATH constant should be defined"
71
+ end
72
+ self.class::URI_PATH
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,75 @@
1
+ require 'backchat_client/http_client'
2
+ require 'backchat_client/backchat_logger'
3
+ require 'active_support'
4
+
5
+ module BackchatClient
6
+
7
+ #
8
+ # A Backchat Stream allows to define a set of channels with filters
9
+ #
10
+ class Stream
11
+ include BackchatClient::HttpClient
12
+ include BackchatClient::BackchatLogger
13
+
14
+ # http uri to handle streams
15
+ URI_PATH = "streams"
16
+
17
+ #
18
+ # @param *api_key* application identifier
19
+ # @param *endpoint* Backchat endpoint
20
+ #
21
+ def initialize(api_key, endpoint)
22
+ @api_key = api_key
23
+ @endpoint = endpoint
24
+ end
25
+
26
+ #
27
+ # This method POST a request to create a new stream on behalf of the
28
+ # authenticated application
29
+ # @param name
30
+ # @param description
31
+ # @param filters one or more valid channel URIs
32
+ # @param filter_enabled one or more boolean values enabling|disabling the filters
33
+ # @return response body
34
+ #
35
+ def create(name, description, filters = [])
36
+ ActiveSupport::JSON.decode(post("", {:name => name, :description => description, :channel_filters => filters}))
37
+ end
38
+
39
+ #
40
+ # Retrieves a stream
41
+ # @param *name* get a stream
42
+ # @return stream data or nil if not found
43
+ #
44
+ def find(name)
45
+ if name
46
+ begin
47
+ ActiveSupport::JSON.decode(get(name))
48
+ rescue RestClient::ResourceNotFound
49
+ return nil
50
+ end
51
+ else
52
+ ActiveSupport::JSON.decode(get("index.json"))
53
+ end
54
+ end
55
+
56
+ def update(slug, params)
57
+ ActiveSupport::JSON.decode(put(slug, params))
58
+ end
59
+
60
+ #
61
+ # Delete a defined stream
62
+ # @param *name* valid stream name
63
+ # @param true|false if deleted or not
64
+ #
65
+ def destroy(name)
66
+ begin
67
+ ActiveSupport::JSON.decode(delete(name))
68
+ return true
69
+ rescue RestClient::ResourceNotFound
70
+ return false
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,57 @@
1
+ require 'active_support'
2
+ require 'backchat_client/http_client'
3
+ require 'backchat_client/backchat_logger'
4
+
5
+ module BackchatClient
6
+
7
+ #
8
+ # A Backchat User is a developer that has an api_key and can create applications using Backchat API
9
+ #
10
+ class User
11
+ include BackchatClient::HttpClient
12
+ include BackchatClient::BackchatLogger
13
+
14
+ URI_PATH = nil # no suffix for user path
15
+
16
+ #
17
+ # @param *api_key* application identifier
18
+ # @param *endpoint* Backchat endpoint
19
+ #
20
+ def initialize(api_key, endpoint)
21
+ @api_key = api_key
22
+ @endpoint = endpoint
23
+ end
24
+
25
+ #
26
+ # Delete user account
27
+ #
28
+ def destroy
29
+ delete("")
30
+ end
31
+
32
+ # this method return the user profile in case that the token provided is valid
33
+ # @return user profile with information about channels, streams and plan
34
+ # @return nil if token is invalid or an unexpected error takes place
35
+ def find
36
+ begin
37
+ debug("Fetching user profile")
38
+ data = get("index.json")
39
+ if data.is_a?(String)
40
+ data = ActiveSupport::JSON.decode(data)
41
+ if data.has_key?("data")
42
+ data["data"]
43
+ else
44
+ nil
45
+ end
46
+ end
47
+ rescue RestClient::Unauthorized => ex
48
+ error "Invalid api_key #{@api_key}"
49
+ nil # Invalid token
50
+ rescue Exception => ex
51
+ logger.error " Unexpected error"
52
+ logger.error ex.inspect
53
+ nil # Unexpected error
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module BackchatClient
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,50 @@
1
+ require 'backchat-client'
2
+ require 'webmock/rspec'
3
+
4
+ describe Backchat::Client do
5
+
6
+ before(:each) do
7
+ Backchat::Client.log_level = Logger::DEBUG
8
+ end
9
+
10
+ describe "it initializes correctly the client" do
11
+
12
+ it "gets the api key and the endpoint" do
13
+ bc = Backchat::Client.new("api-key", "endpoint")
14
+ bc.endpoint.should eq("endpoint")
15
+ bc.api_key.should eq("api-key")
16
+ end
17
+
18
+ it "gets the api key and the default endpoint" do
19
+ bc = Backchat::Client.new("api-key")
20
+ bc.endpoint.should eq(Backchat::Client::DEFAULT_ENDPOINT)
21
+ bc.api_key.should eq("api-key")
22
+ end
23
+
24
+ describe "valid? method" do
25
+ it "returns true with a valid token" do
26
+ api_key = "valid-api-key"
27
+ stub_request(:get, "https://api.backchat.io/1/index.json?").
28
+ with(:headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{api_key}"}).
29
+ to_return(:status => 200, :body => "{'data':{'channels':[],'email':'user@backchat.com','_id':'user_id','api_key':'#{api_key}','last_name':'lastname','first_name':'name','plan':'https://api.backchat.io/1/plans/free','streams':[],'login':'user'},'errors':[]}", :headers => {})
30
+
31
+ bc = Backchat::Client.new(api_key)
32
+ bc.valid?.should eql(true)
33
+ end
34
+
35
+ it "returns false with a valid token" do
36
+ api_key = "invalid-api-key"
37
+ stub_request(:get, "https://api.backchat.io/1/index.json?").
38
+ with(:headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{api_key}"}).
39
+ to_return(:status => 401, :body => "{'data':null,'errors':[['','Unauthorized']]}", :headers => {})
40
+
41
+ bc = Backchat::Client.new(api_key)
42
+ bc.valid?.should eql(false)
43
+ end
44
+ end
45
+
46
+
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,67 @@
1
+ require 'backchat-client'
2
+ require 'webmock/rspec'
3
+
4
+ describe BackchatClient::Channel do
5
+ API_KEY = "valid-api-key"
6
+
7
+ describe "when working with find method" do
8
+
9
+ it "gets all the user defined channels" do
10
+ stub_request(:get, "https://api.backchat.io/1/channels/index.json?").
11
+ with(:headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
12
+ to_return(:body => '{"data":[{"uri":"twitter://pastoret/#timeline"},{"uri":"twitter://juandebravo/#timeline"}],"errors":[]}')
13
+
14
+ bc = Backchat::Client.new(API_KEY)
15
+ channels = bc.find_channel
16
+ channels.should be_a(Array)
17
+ channels.length.should eql(2)
18
+ channels.each { |channel|
19
+ channel.should be_a(Hash)
20
+ channel.should have_key("uri")
21
+ }
22
+ end
23
+
24
+ end
25
+
26
+ describe "when creating a channel" do
27
+ it "returns the channel identifier" do
28
+ stub_request(:post, "https://api.backchat.io/1/channels/index.json").
29
+ with(:body => '{"channel":"twitter://juandebravo"}', :headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
30
+ to_return(:body => '{"data":{"uri":"twitter://juandebravo/#timeline"}, "errors":[]}')
31
+
32
+ bc = Backchat::Client.new(API_KEY)
33
+
34
+ channel = bc.create_channel("twitter", "juandebravo")
35
+ channel.should be_a(Hash)
36
+ channel.should have_key("uri")
37
+ channel["uri"].should eql("twitter://juandebravo/#timeline")
38
+ end
39
+ end
40
+
41
+ describe "when deleting a channel" do
42
+ it "returns ok when the channel exists and force is set to false" do
43
+ pending("need to fix web mock")
44
+ stub_request(:delete, "https://api.backchat.io/1/channels/").
45
+ with(:query => {"channel" => "twitter://juandebravo/#timeline"}, :headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
46
+ to_return(:body => '{"data":{"uri":"twitter://juandebravo/#timeline"}, "errors":[]}')
47
+
48
+ bc = Backchat::Client.new(API_KEY)
49
+ result = bc.destroy_channel("twitter://juandebravo/#timeline")
50
+ result.should eql(true)
51
+ end
52
+
53
+ it "returns ok when the channel exists and force is set to true" do
54
+ pending("need to fix web mock")
55
+ stub_request(:delete, "https://api.backchat.io/1/channels/").
56
+ with(:query => {"channel" => "twitter://juandebravo/#timeline", "force" => "true"}, :headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
57
+ to_return(:body => '{"data":{"uri":"twitter://juandebravo/#timeline"}, "errors":[]}')
58
+
59
+ bc = Backchat::Client.new(API_KEY)
60
+ result = bc.destroy_channel("twitter://juandebravo/#timeline", true)
61
+ result.should eql(true)
62
+ end
63
+
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,38 @@
1
+ require 'backchat-client'
2
+ require 'webmock/rspec'
3
+
4
+ describe BackchatClient::Stream do
5
+ API_KEY = "valid_api_key"
6
+
7
+ before(:each) do
8
+ Backchat::Client.log_level = Logger::DEBUG
9
+ end
10
+
11
+ describe "when working with find method" do
12
+
13
+ it "gets all the user defined streams when no name is provided" do
14
+ pending
15
+ end
16
+
17
+ it "gets a specific stream when name is provided" do
18
+ pending
19
+ end
20
+
21
+ end
22
+
23
+ describe "when creating a stream" do
24
+ it "returns the stream identifier" do
25
+ pending
26
+ bc = Backchat::Client.new(API_KEY)
27
+ puts bc.create_stream("stream-name", nil, [{:channel => "twitter://juandebravo/#timeline", :enabled => true}])
28
+ end
29
+ end
30
+
31
+ describe "when deleting a stream" do
32
+ it "returns ok when the stream exists" do
33
+ pending
34
+ bc = Backchat::Client.new(API_KEY)
35
+ puts bc.destroy_stream("stream-name")
36
+ end
37
+ end
38
+ end
data/spec/user_spec.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'backchat-client'
2
+ require 'webmock/rspec'
3
+
4
+ describe BackchatClient::User do
5
+
6
+ before(:each) do
7
+ Backchat::Client.log_level = Logger::DEBUG
8
+ end
9
+
10
+ describe "when working with find method" do
11
+
12
+ it "gets all the user defined streams when no name is provided" do
13
+ API_KEY = "valid_api_key"
14
+ bc = Backchat::Client.new(API_KEY)
15
+ stub_request(:get, "https://api.backchat.io/1/index.json?").
16
+ with(:headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
17
+ to_return(:status => 200, :body => "{'data':{'channels':[{'uri':'smtp://user.channel/'}, {'uri':'twitter://username'}],'email':'user@backchat.com','_id':'user_id','api_key':'#{API_KEY}','last_name':'lastname','first_name':'name','plan':'https://api.backchat.io/1/plans/free','streams':['https://api.backchat.io/1/streams/user-stream'],'login':'user'},'errors':[]}", :headers => {})
18
+
19
+ profile = bc.get_profile
20
+ ["channels", "email", "api_key"].each{|key|
21
+ profile.should have_key(key)
22
+ }
23
+ end
24
+
25
+ it "deletes a user when valid api_key provided" do
26
+ API_KEY = "valid_api_key"
27
+ bc = Backchat::Client.new(API_KEY)
28
+ stub_request(:delete, "https://api.backchat.io/1/?").
29
+ with(:headers => {'Accept'=>'application/json', 'Authorization' => "Backchat #{API_KEY}"}).
30
+ to_return(:status => 200, :body => "", :headers => {})
31
+
32
+ result = bc.delete_user
33
+ result.should eql("")
34
+ end
35
+
36
+ end
37
+
38
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: backchat-client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: "0.1"
6
+ platform: ruby
7
+ authors:
8
+ - This gem provides an easy way to access Backchat provisioning API
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-26 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rest-client
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: addressable
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: webmock
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id005
71
+ description: Gem to access Backchat provisioning API using rest_client as http client
72
+ email:
73
+ - juandebravo@gmail.com
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ extra_rdoc_files: []
79
+
80
+ files:
81
+ - .gitignore
82
+ - .rspec
83
+ - Gemfile
84
+ - LICENSE
85
+ - README.md
86
+ - Rakefile
87
+ - backchat-client.gemspec
88
+ - examples/add_channel_to_stream.rb
89
+ - examples/create_channel.rb
90
+ - examples/create_stream.rb
91
+ - examples/delete_channel.rb
92
+ - examples/delete_stream.rb
93
+ - examples/delete_user.rb
94
+ - examples/get_channels.rb
95
+ - examples/stream.rb
96
+ - examples/user.rb
97
+ - lib/backchat-client.rb
98
+ - lib/backchat_client/backchat_logger.rb
99
+ - lib/backchat_client/channel.rb
100
+ - lib/backchat_client/http_client.rb
101
+ - lib/backchat_client/stream.rb
102
+ - lib/backchat_client/user.rb
103
+ - lib/backchat_client/version.rb
104
+ - spec/backchat-client_spec.rb
105
+ - spec/channel_spec.rb
106
+ - spec/streams_spec.rb
107
+ - spec/user_spec.rb
108
+ has_rdoc: true
109
+ homepage: ""
110
+ licenses: []
111
+
112
+ post_install_message:
113
+ rdoc_options: []
114
+
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: "0"
129
+ requirements: []
130
+
131
+ rubyforge_project: backchat-client
132
+ rubygems_version: 1.6.2
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Gem to access Backchat provisioning API
136
+ test_files:
137
+ - spec/backchat-client_spec.rb
138
+ - spec/channel_spec.rb
139
+ - spec/streams_spec.rb
140
+ - spec/user_spec.rb