connfu-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.
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