connfu-client 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +3 -0
- data/.rvmrc +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +120 -0
- data/LICENSE.txt +661 -0
- data/README.rdoc +398 -0
- data/Rakefile +38 -0
- data/bin/.DS_Store +0 -0
- data/bin/connfu-client +94 -0
- data/connfu-client.gemspec +41 -0
- data/examples/conference/application.rb +68 -0
- data/examples/conference/conference.rb +33 -0
- data/examples/conference/conference_app.rb +25 -0
- data/examples/conference/connfu.log +5 -0
- data/examples/conference/wall.rb +11 -0
- data/examples/provisioning/app/get.rb +29 -0
- data/examples/provisioning/channels/get.rb +34 -0
- data/examples/provisioning/rss/create.rb +28 -0
- data/examples/provisioning/rss/delete.rb +27 -0
- data/examples/provisioning/rss/get.rb +32 -0
- data/examples/provisioning/rss/put.rb +29 -0
- data/examples/provisioning/setup.rb +2 -0
- data/examples/provisioning/twitter/create.rb +31 -0
- data/examples/provisioning/twitter/delete.rb +27 -0
- data/examples/provisioning/twitter/get.rb +32 -0
- data/examples/provisioning/twitter/put.rb +29 -0
- data/examples/provisioning/voice/create.rb +26 -0
- data/examples/provisioning/voice/delete.rb +27 -0
- data/examples/provisioning/voice/get.rb +36 -0
- data/examples/provisioning/voice/phones/create.rb +26 -0
- data/examples/provisioning/voice/phones/delete.rb +28 -0
- data/examples/provisioning/voice/phones/get.rb +38 -0
- data/examples/provisioning/voice/put.rb +38 -0
- data/examples/provisioning/voice/whitelist/create.rb +26 -0
- data/examples/provisioning/voice/whitelist/delete.rb +27 -0
- data/examples/provisioning/voice/whitelist/get.rb +36 -0
- data/examples/provisioning/voice/whitelist/put.rb +27 -0
- data/lib/connfu.rb +134 -0
- data/lib/connfu/cli/generator.rb +71 -0
- data/lib/connfu/connfu_logger.rb +88 -0
- data/lib/connfu/connfu_message_formatter.rb +134 -0
- data/lib/connfu/connfu_stream.rb +182 -0
- data/lib/connfu/dispatcher.rb +164 -0
- data/lib/connfu/dsl.rb +84 -0
- data/lib/connfu/events.rb +32 -0
- data/lib/connfu/listener.rb +85 -0
- data/lib/connfu/listener_channel.rb +100 -0
- data/lib/connfu/message.rb +74 -0
- data/lib/connfu/provisioning.rb +12 -0
- data/lib/connfu/provisioning/application.rb +374 -0
- data/lib/connfu/provisioning/base.rb +95 -0
- data/lib/connfu/provisioning/channel.rb +79 -0
- data/lib/connfu/provisioning/phone.rb +55 -0
- data/lib/connfu/provisioning/rss.rb +21 -0
- data/lib/connfu/provisioning/twitter.rb +28 -0
- data/lib/connfu/provisioning/voice.rb +89 -0
- data/lib/connfu/provisioning/whitelist.rb +62 -0
- data/lib/connfu/version.rb +6 -0
- data/lib/rdoc/generator/template/connfu/_context.rhtml +209 -0
- data/lib/rdoc/generator/template/connfu/_head.rhtml +7 -0
- data/lib/rdoc/generator/template/connfu/class.rhtml +38 -0
- data/lib/rdoc/generator/template/connfu/file.rhtml +36 -0
- data/lib/rdoc/generator/template/connfu/index.rhtml +13 -0
- data/lib/rdoc/generator/template/connfu/resources/apple-touch-icon.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/css/github.css +129 -0
- data/lib/rdoc/generator/template/connfu/resources/css/main.css +339 -0
- data/lib/rdoc/generator/template/connfu/resources/css/panel.css +389 -0
- data/lib/rdoc/generator/template/connfu/resources/css/reset.css +53 -0
- data/lib/rdoc/generator/template/connfu/resources/favicon.ico +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/arrows.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/results_bg.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/tree_bg.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/js/highlight.pack.js +1 -0
- data/lib/rdoc/generator/template/connfu/resources/js/jquery-1.3.2.min.js +19 -0
- data/lib/rdoc/generator/template/connfu/resources/js/jquery-effect.js +593 -0
- data/lib/rdoc/generator/template/connfu/resources/js/main.js +20 -0
- data/lib/rdoc/generator/template/connfu/resources/js/searchdoc.js +628 -0
- data/lib/rdoc/generator/template/connfu/resources/panel/index.html +72 -0
- data/lib/rdoc/generator/template/connfu/se_index.rhtml +8 -0
- data/spec/connfu_message_formatter_spec.rb +88 -0
- data/spec/connfu_spec.rb +51 -0
- data/spec/connfu_stream_spec.rb +84 -0
- data/spec/dispatcher_spec.rb +227 -0
- data/spec/dsl_spec.rb +159 -0
- data/spec/listener_channel_spec.rb +130 -0
- data/spec/listener_spec.rb +67 -0
- data/spec/provisioning/application_spec.rb +47 -0
- data/spec/provisioning/channel_shared_examples.rb +52 -0
- data/spec/provisioning/channel_spec.rb +13 -0
- data/spec/provisioning/phone_spec.rb +88 -0
- data/spec/provisioning/voice_spec.rb +138 -0
- data/spec/provisioning_spec.rb +500 -0
- data/spec/spec_helper.rb +51 -0
- metadata +298 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
|
3
|
+
module Connfu
|
4
|
+
module Provisioning
|
5
|
+
|
6
|
+
##
|
7
|
+
# This class is the responsible of any HTTP request to connFu endpoint
|
8
|
+
#
|
9
|
+
class Base
|
10
|
+
|
11
|
+
# valid api_key that authenticates the application
|
12
|
+
attr_accessor :api_key
|
13
|
+
|
14
|
+
# Connfu endpoint (host:port)
|
15
|
+
attr_accessor :endpoint
|
16
|
+
|
17
|
+
##
|
18
|
+
# Initializer
|
19
|
+
# ==== Parameters
|
20
|
+
# * +api_key+ valid api_key that authenticates the application
|
21
|
+
# * +endpoint+ Connfu endpoint (host:port)
|
22
|
+
#
|
23
|
+
def initialize(api_key, endpoint = nil)
|
24
|
+
@api_key = api_key
|
25
|
+
@endpoint = endpoint.nil? ? Base.endpoint : endpoint # if no endpoint retrieved, try to use the class one
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# HTTP GET request
|
30
|
+
#
|
31
|
+
def get(path, params = {}, headers = {})
|
32
|
+
headers.merge!(base_headers).merge!({:Accept => "application/json"})
|
33
|
+
RestClient.get("#{@endpoint}/#{path}?".concat(params.collect { |k, v| "#{k}=#{v.to_s}" }.join("&")), headers)
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# HTTP POST request
|
38
|
+
#
|
39
|
+
def post(path, body = {}, headers = {})
|
40
|
+
headers.merge!(base_headers).merge!({:content_type => :json, :Accept => "application/json"})
|
41
|
+
RestClient.post("#{@endpoint}/#{path}", ActiveSupport::JSON.encode(body), headers) { |response, request, result|
|
42
|
+
case response.code
|
43
|
+
when 200..201
|
44
|
+
# If there is a :location header, return it
|
45
|
+
if response.headers.has_key?(:location)
|
46
|
+
return response.headers[:location]
|
47
|
+
end
|
48
|
+
# else, do the normal stuff
|
49
|
+
if block_given?
|
50
|
+
response.return!(request, result, &Proc.new)
|
51
|
+
else
|
52
|
+
response.return!(request, result)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
if block_given?
|
56
|
+
response.return!(request, result, &Proc.new)
|
57
|
+
else
|
58
|
+
response.return!(request, result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# HTTP PUT request
|
66
|
+
#
|
67
|
+
def put(path, body = {}, headers = {})
|
68
|
+
headers.merge!(base_headers).merge!({:content_type => :json, :Accept => "application/json"})
|
69
|
+
RestClient.put("#{@endpoint}/#{path}", ActiveSupport::JSON.encode(body), headers)
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# HTTP DELETE request
|
74
|
+
#
|
75
|
+
def delete(path, params = {}, headers = {})
|
76
|
+
headers.merge!(base_headers).merge!({:content_type => :json, :Accept => "application/json"})
|
77
|
+
RestClient.delete("#{@endpoint}/#{path}?".concat(params.collect { |k, v| "#{k}=#{v.to_s}" }.join("&")), headers)
|
78
|
+
end
|
79
|
+
|
80
|
+
class << self
|
81
|
+
# Enable to configure just once the endpoint
|
82
|
+
attr_accessor :endpoint
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
##
|
88
|
+
# Required HTTP headers to be sent in each request
|
89
|
+
def base_headers
|
90
|
+
{:AUTH_TOKEN => "#{@api_key}", :REQUEST_ID => "#{@api_key[0..10]}#{Time.now.to_i.to_s}"}
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
module Connfu
|
3
|
+
module Provisioning
|
4
|
+
|
5
|
+
##
|
6
|
+
# Channel class models a connFu application channel. Its the superclass of Twitter and Voice and any other
|
7
|
+
# forthcoming connFu channel
|
8
|
+
class Channel
|
9
|
+
|
10
|
+
# created at timestamp
|
11
|
+
attr_accessor :created_at
|
12
|
+
|
13
|
+
# updated at timestamp
|
14
|
+
attr_accessor :updated_at
|
15
|
+
|
16
|
+
# channel unique identifier
|
17
|
+
attr_accessor :uid
|
18
|
+
|
19
|
+
# channel type
|
20
|
+
attr_accessor :type
|
21
|
+
|
22
|
+
# Creates a Channel instance using a Hash values
|
23
|
+
# It creates an instance variable per each hash key
|
24
|
+
def initialize(params)
|
25
|
+
self.type = self.class.to_s.downcase
|
26
|
+
params.each_pair { |key, value|
|
27
|
+
self.instance_variable_set("@#{key}", value)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Creates a hash with the instance info
|
32
|
+
def to_hash
|
33
|
+
{"uid" => uid}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Print object using metaprogramming. This method is used by any child class
|
37
|
+
def to_s
|
38
|
+
value = []
|
39
|
+
self.instance_variables.each { |var|
|
40
|
+
value << "#{var[1..-1]}: #{self.instance_variable_get(var)}"
|
41
|
+
}
|
42
|
+
self.class.name + "{\n" + value.join("\t\n").to_s + "\n}"
|
43
|
+
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
|
47
|
+
##
|
48
|
+
#
|
49
|
+
# Creates a Channel instance (or a Channel child class instance) object or an Array using a Hash values
|
50
|
+
#
|
51
|
+
# ==== Parameters
|
52
|
+
#
|
53
|
+
# * +data+ - hash containing channel information retrieved using the connFu API
|
54
|
+
def unmarshal(data)
|
55
|
+
|
56
|
+
# Helper to get the channel class using the type attribute (we are
|
57
|
+
# retrieving all the channels) or the client class (we are retrieving
|
58
|
+
# specific a channel type)
|
59
|
+
create_channel = lambda { |channel|
|
60
|
+
if channel.has_key?("type") # get the class from type attribute (get all channels)
|
61
|
+
type = channel["type"].capitalize
|
62
|
+
Connfu::Provisioning.const_get(type).new(channel)
|
63
|
+
else # get the class from class
|
64
|
+
self.new(channel)
|
65
|
+
end
|
66
|
+
}
|
67
|
+
|
68
|
+
if data.is_a?(Array) # more than one element
|
69
|
+
data.map { |channel| create_channel.call(channel) }
|
70
|
+
else # one element
|
71
|
+
create_channel.call(data)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Connfu
|
2
|
+
|
3
|
+
module Provisioning
|
4
|
+
|
5
|
+
#
|
6
|
+
# connFu Phone (belongs to a Voice channel)
|
7
|
+
#
|
8
|
+
class Phone
|
9
|
+
|
10
|
+
# specific country where the phone is allocated
|
11
|
+
attr_accessor :country
|
12
|
+
|
13
|
+
# phone number
|
14
|
+
attr_accessor :phone_number
|
15
|
+
|
16
|
+
# voice channel unique identifier
|
17
|
+
attr_reader :voice
|
18
|
+
|
19
|
+
# @param voice voice channel identifier
|
20
|
+
# @param phone_number
|
21
|
+
# @param country
|
22
|
+
def initialize(voice, phone_number, country = "")
|
23
|
+
@voice = voice
|
24
|
+
@phone_number = phone_number
|
25
|
+
@country = country
|
26
|
+
end
|
27
|
+
|
28
|
+
# Hash way to retrieve attributes
|
29
|
+
def [](value)
|
30
|
+
self.respond_to?(value.to_sym) ? self.send(value.to_sym) : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
{"country" => country, "phone_number" => phone_number}
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
"#{self.class.to_s}: #{to_hash}"
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Creates a Phone object using the raw data from the provisioning API
|
43
|
+
# @param voice channel unique identifier
|
44
|
+
# @param data Hash containing the raw data
|
45
|
+
def self.unmarshal(voice, data)
|
46
|
+
if data.is_a?(Array)
|
47
|
+
data.map{|item| Phone.new(voice, item["phone_number"], item["country"])}
|
48
|
+
else
|
49
|
+
Phone.new(voice, data["phone_number"], data["country"])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Connfu
|
2
|
+
module Provisioning
|
3
|
+
|
4
|
+
# This class models s connFu RSS channel
|
5
|
+
class Rss < Channel
|
6
|
+
|
7
|
+
# RSS URI
|
8
|
+
attr_accessor :uri
|
9
|
+
|
10
|
+
def initialize(params)
|
11
|
+
super(params)
|
12
|
+
self.type = "rss"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
{"uid" => uid, "type" => type, "uri" => uri}
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module Connfu
|
3
|
+
module Provisioning
|
4
|
+
|
5
|
+
#
|
6
|
+
# This class models a connFu Twitter channel
|
7
|
+
#
|
8
|
+
class Twitter < Channel
|
9
|
+
|
10
|
+
# Twitter accounts associated to that Twitter channel
|
11
|
+
attr_accessor :accounts
|
12
|
+
|
13
|
+
# string that filters the tweets to retrieve only the desired hashtag
|
14
|
+
attr_accessor :filter
|
15
|
+
|
16
|
+
def initialize(params)
|
17
|
+
super(params)
|
18
|
+
self.type = "twitter"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a hash with the Twitter instance info
|
22
|
+
def to_hash
|
23
|
+
{"uid" => uid, "type" => type, "accounts" => accounts, "filter" => filter}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'connfu/provisioning/whitelist'
|
2
|
+
|
3
|
+
module Connfu
|
4
|
+
|
5
|
+
module Provisioning
|
6
|
+
|
7
|
+
##
|
8
|
+
# This class models a connFu Voice channel
|
9
|
+
#
|
10
|
+
class Voice < Channel
|
11
|
+
|
12
|
+
class Privacy
|
13
|
+
WHITELIST = "whitelisted"
|
14
|
+
PUBLIC = "public"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Voice channel attributes that could be updated
|
18
|
+
UPDATE_ATTRIBUTES = ["topic", "welcome_message", "rejected_message", "privacy"]
|
19
|
+
|
20
|
+
_values = UPDATE_ATTRIBUTES.dup
|
21
|
+
_values.each { |value|
|
22
|
+
UPDATE_ATTRIBUTES << value.to_sym
|
23
|
+
}
|
24
|
+
UPDATE_ATTRIBUTES.freeze
|
25
|
+
UPDATE_ATTRIBUTES.each { |value| value.freeze }
|
26
|
+
|
27
|
+
# current topic
|
28
|
+
attr_accessor :topic
|
29
|
+
|
30
|
+
# welcome message for valid users while joining the conference
|
31
|
+
attr_accessor :welcome_message
|
32
|
+
|
33
|
+
# rejected message for invalid users while trying to join the conference
|
34
|
+
attr_accessor :rejected_message
|
35
|
+
|
36
|
+
# Identifies if the conference is open to any phone number or users must
|
37
|
+
# be whitelisted to join the conference
|
38
|
+
attr_accessor :privacy
|
39
|
+
|
40
|
+
def initialize(params)
|
41
|
+
super(params)
|
42
|
+
self.type = "voice"
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_hash
|
46
|
+
{"uid" => uid, "type" => type, "phones" => phones.map(&:to_hash)}
|
47
|
+
end
|
48
|
+
|
49
|
+
# access the Voice channel Whitelist
|
50
|
+
def whitelist
|
51
|
+
Whitelist.new(@name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Retrieves the phone numbers
|
55
|
+
def phone_number
|
56
|
+
values = phones.collect{|phone| phone[:phone_number]}
|
57
|
+
end
|
58
|
+
|
59
|
+
def phones
|
60
|
+
@phones||=[]
|
61
|
+
end
|
62
|
+
|
63
|
+
def phones=(_phones)
|
64
|
+
@phones=_phones
|
65
|
+
end
|
66
|
+
|
67
|
+
def <<(phone)
|
68
|
+
phones << phone
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
|
73
|
+
# Creates a Voice object or an Array using a Hash values
|
74
|
+
def unmarshal(data)
|
75
|
+
obj = super(data)
|
76
|
+
if obj.is_a?(Array) # more than one element
|
77
|
+
obj.each { |voice|
|
78
|
+
voice.phones = voice.phones.map { |phone| Phone.new(voice.uid, phone["phone_number"], phone["country"]) }
|
79
|
+
}
|
80
|
+
else # one element
|
81
|
+
obj.phones = obj.phones.map { |phone| Phone.new(obj.uid, phone["phone_number"], phone["country"]) }
|
82
|
+
obj
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Connfu
|
2
|
+
|
3
|
+
module Provisioning
|
4
|
+
|
5
|
+
##
|
6
|
+
# This class defines a whitelist user (whitelist item)
|
7
|
+
WhitelistUser = Struct.new(:name, :phone)
|
8
|
+
|
9
|
+
##
|
10
|
+
# This class models a conference whitelist
|
11
|
+
class Whitelist
|
12
|
+
|
13
|
+
# WhitelistUser array
|
14
|
+
attr_accessor :users
|
15
|
+
|
16
|
+
# Conference phone
|
17
|
+
attr_reader :voice
|
18
|
+
|
19
|
+
def initialize(voice, users = [])
|
20
|
+
@voice = voice
|
21
|
+
@users = users
|
22
|
+
end
|
23
|
+
|
24
|
+
# Iterator based on users array
|
25
|
+
def each
|
26
|
+
users.each{|user|
|
27
|
+
yield user
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
value = []
|
33
|
+
self.instance_variables.each { |var|
|
34
|
+
value << "#{var}: #{self.instance_variable_get(var)}"
|
35
|
+
}
|
36
|
+
value.join("\n").to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Creates a Whitelist object using the raw data from the provisioning API
|
41
|
+
# ==== Parameters
|
42
|
+
# * +voice+ voice channel unique identifier
|
43
|
+
# * +data+ raw data retrieved using the connFu API
|
44
|
+
def self.unmarshal(voice, data)
|
45
|
+
|
46
|
+
if data.is_a?(Array)
|
47
|
+
numbers = []
|
48
|
+
data.each { |number|
|
49
|
+
numbers << WhitelistUser.new(*number.values)
|
50
|
+
|
51
|
+
}
|
52
|
+
users = numbers
|
53
|
+
else
|
54
|
+
users = [WhitelistUser.new(*data.values)]
|
55
|
+
end
|
56
|
+
Whitelist.new(voice, users)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|