backchat-client 0.1

Sign up to get free protection for your applications and to get access to all the features.
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