connfu-client 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/.rspec +3 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +120 -0
  5. data/LICENSE.txt +661 -0
  6. data/README.rdoc +398 -0
  7. data/Rakefile +38 -0
  8. data/bin/.DS_Store +0 -0
  9. data/bin/connfu-client +94 -0
  10. data/connfu-client.gemspec +41 -0
  11. data/examples/conference/application.rb +68 -0
  12. data/examples/conference/conference.rb +33 -0
  13. data/examples/conference/conference_app.rb +25 -0
  14. data/examples/conference/connfu.log +5 -0
  15. data/examples/conference/wall.rb +11 -0
  16. data/examples/provisioning/app/get.rb +29 -0
  17. data/examples/provisioning/channels/get.rb +34 -0
  18. data/examples/provisioning/rss/create.rb +28 -0
  19. data/examples/provisioning/rss/delete.rb +27 -0
  20. data/examples/provisioning/rss/get.rb +32 -0
  21. data/examples/provisioning/rss/put.rb +29 -0
  22. data/examples/provisioning/setup.rb +2 -0
  23. data/examples/provisioning/twitter/create.rb +31 -0
  24. data/examples/provisioning/twitter/delete.rb +27 -0
  25. data/examples/provisioning/twitter/get.rb +32 -0
  26. data/examples/provisioning/twitter/put.rb +29 -0
  27. data/examples/provisioning/voice/create.rb +26 -0
  28. data/examples/provisioning/voice/delete.rb +27 -0
  29. data/examples/provisioning/voice/get.rb +36 -0
  30. data/examples/provisioning/voice/phones/create.rb +26 -0
  31. data/examples/provisioning/voice/phones/delete.rb +28 -0
  32. data/examples/provisioning/voice/phones/get.rb +38 -0
  33. data/examples/provisioning/voice/put.rb +38 -0
  34. data/examples/provisioning/voice/whitelist/create.rb +26 -0
  35. data/examples/provisioning/voice/whitelist/delete.rb +27 -0
  36. data/examples/provisioning/voice/whitelist/get.rb +36 -0
  37. data/examples/provisioning/voice/whitelist/put.rb +27 -0
  38. data/lib/connfu.rb +134 -0
  39. data/lib/connfu/cli/generator.rb +71 -0
  40. data/lib/connfu/connfu_logger.rb +88 -0
  41. data/lib/connfu/connfu_message_formatter.rb +134 -0
  42. data/lib/connfu/connfu_stream.rb +182 -0
  43. data/lib/connfu/dispatcher.rb +164 -0
  44. data/lib/connfu/dsl.rb +84 -0
  45. data/lib/connfu/events.rb +32 -0
  46. data/lib/connfu/listener.rb +85 -0
  47. data/lib/connfu/listener_channel.rb +100 -0
  48. data/lib/connfu/message.rb +74 -0
  49. data/lib/connfu/provisioning.rb +12 -0
  50. data/lib/connfu/provisioning/application.rb +374 -0
  51. data/lib/connfu/provisioning/base.rb +95 -0
  52. data/lib/connfu/provisioning/channel.rb +79 -0
  53. data/lib/connfu/provisioning/phone.rb +55 -0
  54. data/lib/connfu/provisioning/rss.rb +21 -0
  55. data/lib/connfu/provisioning/twitter.rb +28 -0
  56. data/lib/connfu/provisioning/voice.rb +89 -0
  57. data/lib/connfu/provisioning/whitelist.rb +62 -0
  58. data/lib/connfu/version.rb +6 -0
  59. data/lib/rdoc/generator/template/connfu/_context.rhtml +209 -0
  60. data/lib/rdoc/generator/template/connfu/_head.rhtml +7 -0
  61. data/lib/rdoc/generator/template/connfu/class.rhtml +38 -0
  62. data/lib/rdoc/generator/template/connfu/file.rhtml +36 -0
  63. data/lib/rdoc/generator/template/connfu/index.rhtml +13 -0
  64. data/lib/rdoc/generator/template/connfu/resources/apple-touch-icon.png +0 -0
  65. data/lib/rdoc/generator/template/connfu/resources/css/github.css +129 -0
  66. data/lib/rdoc/generator/template/connfu/resources/css/main.css +339 -0
  67. data/lib/rdoc/generator/template/connfu/resources/css/panel.css +389 -0
  68. data/lib/rdoc/generator/template/connfu/resources/css/reset.css +53 -0
  69. data/lib/rdoc/generator/template/connfu/resources/favicon.ico +0 -0
  70. data/lib/rdoc/generator/template/connfu/resources/i/arrows.png +0 -0
  71. data/lib/rdoc/generator/template/connfu/resources/i/results_bg.png +0 -0
  72. data/lib/rdoc/generator/template/connfu/resources/i/tree_bg.png +0 -0
  73. data/lib/rdoc/generator/template/connfu/resources/js/highlight.pack.js +1 -0
  74. data/lib/rdoc/generator/template/connfu/resources/js/jquery-1.3.2.min.js +19 -0
  75. data/lib/rdoc/generator/template/connfu/resources/js/jquery-effect.js +593 -0
  76. data/lib/rdoc/generator/template/connfu/resources/js/main.js +20 -0
  77. data/lib/rdoc/generator/template/connfu/resources/js/searchdoc.js +628 -0
  78. data/lib/rdoc/generator/template/connfu/resources/panel/index.html +72 -0
  79. data/lib/rdoc/generator/template/connfu/se_index.rhtml +8 -0
  80. data/spec/connfu_message_formatter_spec.rb +88 -0
  81. data/spec/connfu_spec.rb +51 -0
  82. data/spec/connfu_stream_spec.rb +84 -0
  83. data/spec/dispatcher_spec.rb +227 -0
  84. data/spec/dsl_spec.rb +159 -0
  85. data/spec/listener_channel_spec.rb +130 -0
  86. data/spec/listener_spec.rb +67 -0
  87. data/spec/provisioning/application_spec.rb +47 -0
  88. data/spec/provisioning/channel_shared_examples.rb +52 -0
  89. data/spec/provisioning/channel_spec.rb +13 -0
  90. data/spec/provisioning/phone_spec.rb +88 -0
  91. data/spec/provisioning/voice_spec.rb +138 -0
  92. data/spec/provisioning_spec.rb +500 -0
  93. data/spec/spec_helper.rb +51 -0
  94. 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
@@ -0,0 +1,6 @@
1
+
2
+ module Connfu
3
+ ##
4
+ # Current connFu DSL version
5
+ VERSION = "0.1"
6
+ end