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,74 @@
1
+
2
+ module Connfu
3
+
4
+ ##
5
+ # This class provides the relevant information got from an external event
6
+ #
7
+ class Message
8
+
9
+ # valid voice messages
10
+ VOICE_TYPES = ["join", "leave", "new_topic"]
11
+
12
+ # valid sms messages
13
+ SMS_TYPES = ["sms"]
14
+
15
+ attr_reader :id # external identifier
16
+ attr_reader :content # main content
17
+ attr_reader :from # sender
18
+ attr_reader :to # receiver
19
+ attr_reader :message_type # new, join
20
+ attr_reader :channel_type # twitter, voice, sms, rss, etc
21
+ attr_accessor :channel_name # specific channel (twitter account, etc)
22
+
23
+ ##
24
+ # Initializer
25
+ def initialize(params)
26
+ params.each_pair { |key, value|
27
+ self.instance_variable_set("@#{key}", value)
28
+ }
29
+ end
30
+
31
+ ##
32
+ # Trying to show the information properly
33
+ def to_s
34
+ value = []
35
+ self.instance_variables.each { |var|
36
+ value << "#{var[1..-1]}: #{self.instance_variable_get(var)}"
37
+ }
38
+ value.join("; ").to_s
39
+ end
40
+
41
+ ##
42
+ # Retrieve an attribute using a Hash approach
43
+ # ==== Parameters
44
+ # * +value+ attribute name
45
+ # ==== Return
46
+ # attribute value
47
+ def [](value)
48
+ self.instance_variable_get("@#{value.to_s}")
49
+ end
50
+
51
+ class << self
52
+ ##
53
+ # Checks if a message is a valid voice message (If it is included in VOICE_TYPES)
54
+ # ==== Parameters
55
+ # * +type+ message type
56
+ # ==== Return
57
+ # true if the message is a voice message, false if not
58
+ def is_voice?(type)
59
+ VOICE_TYPES.include?(type)
60
+ end
61
+
62
+ ##
63
+ # Checks if a message is a valid sms message (If it is included in SMS_TYPES)
64
+ # ==== Parameters
65
+ # * +type+ message type
66
+ # ==== Return
67
+ # true if the message is a sms message, false if not
68
+ def is_sms?(type)
69
+ SMS_TYPES.include?(type)
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ require 'connfu/provisioning/application'
2
+ require 'connfu/provisioning/base'
3
+ require 'connfu/provisioning/channel'
4
+ require 'connfu/provisioning/phone'
5
+ require 'connfu/provisioning/rss'
6
+ require 'connfu/provisioning/twitter'
7
+ require 'connfu/provisioning/voice'
8
+
9
+ module Connfu
10
+ module Provisioning
11
+ end
12
+ end
@@ -0,0 +1,374 @@
1
+ require 'active_support'
2
+
3
+ module Connfu
4
+ module Provisioning
5
+
6
+ ##
7
+ # Application class defines the single entry point to fetch, create, update and delete
8
+ # any channel associated to the application
9
+ #
10
+ class Application
11
+ # Base instance to send HTTP requests to connFu API
12
+ attr_accessor :base
13
+
14
+ ##
15
+ # Initializer
16
+ # ==== Parameters
17
+ #
18
+ # * +api_key+ valid api_key that authenticates the application
19
+ # * +endpoint+ connFu endpoint (host:port). Optional
20
+ def initialize(api_key, endpoint = Connfu::CONNFU_ENDPOINT)
21
+ @base = Base.new(api_key, endpoint)
22
+ @name = nil
23
+ @description = nil
24
+ @stream_name = nil
25
+ end
26
+
27
+ ##
28
+ # Retrieves the app information using the API
29
+ # ==== Return
30
+ # * +self+ instance with name, description and stream_name updated
31
+ # * raise RestClient::Unauthorized if token is invalid
32
+ def get_info
33
+ if @name.nil?
34
+ data = ActiveSupport::JSON.decode(@base.get(""))
35
+ unless data.nil? or !data.instance_of?(Hash)
36
+ @name = data["name"]
37
+ @description = data["description"]
38
+ @stream_name = data["stream_name"]
39
+ end
40
+ end
41
+ self
42
+ end
43
+
44
+ ##
45
+ # Returns the app name. Lazy loading, it sends a request to retrieve application info
46
+ # only the first time this method is called, and the info is cached for next calls
47
+ # ==== Return
48
+ # application name
49
+ def name
50
+ @name.nil? and get_info
51
+ @name
52
+ end
53
+
54
+
55
+ ##
56
+ # Returns the app description. Lazy loading, it sends a request to retrieve application info
57
+ # only the first time this method is called, and the info is cached for next calls
58
+ # ==== Return
59
+ # application description
60
+ def description
61
+ @name.nil? and get_info
62
+ @description
63
+ end
64
+
65
+ ##
66
+ # Returns the app stream name. Lazy loading, it sends a request to retrieve application info
67
+ # only the first time this method is called, and the info is cached for next calls
68
+ # ==== Return
69
+ # application stream name
70
+ def stream_name
71
+ @name.nil? and get_info
72
+ @stream_name
73
+ end
74
+
75
+ ##
76
+ # Retrieves the app channels
77
+ # ==== Return
78
+ # Array of Channel instances
79
+ def get_channels
80
+ data = ActiveSupport::JSON.decode(@base.get("channels/"))
81
+ Channel.unmarshal(data)
82
+ end
83
+
84
+ #
85
+ # Twitter channel management
86
+ #
87
+ # Retrieve the Twitter channel
88
+ # @param key Twitter channel identifier. It it is not specified, all the twitter channels are fetched
89
+ #
90
+ def get_twitter_channel(key = "")
91
+ data = ActiveSupport::JSON.decode(@base.get("channels/twitter/#{key}"))
92
+ Twitter.unmarshal(data)
93
+ end
94
+
95
+ #
96
+ # @TODO
97
+ #
98
+ def update_twitter_channel()
99
+
100
+ end
101
+
102
+ ##
103
+ # Create a Twitter channel per each of the origin or recipients
104
+ #
105
+ # ==== Parameters
106
+ #
107
+ # * +key+ Twitter channel identifier
108
+ # * +params+ Twitter channel behavior
109
+ # - array object of origin twitter accounts
110
+ # - Hash object
111
+ # - origin: one or more twitter accounts
112
+ # - mentions: one or more twitter accounts
113
+ # - hashtags: one or more hashtags
114
+ def create_twitter_channel(key, params = {:origin => [], :mentions => [], :hashtags => []})
115
+
116
+ if params.is_a?(Array)
117
+ _params = {}
118
+ _params[:origin] = params
119
+ params = _params
120
+ elsif params.is_a?(String)
121
+ _params = {}
122
+ _params[:origin] = params
123
+ params = _params
124
+ end
125
+
126
+ unless params.has_key?(:origin) or params.has_key?(:mentions)
127
+ raise "Invalid parameters. Either origin or mentions should be defined"
128
+ end
129
+
130
+ if params.has_key?(:origin) and params.has_key?(:mentions)
131
+ raise "Invalid parameters. Only origin or mentions can be defined"
132
+ end
133
+
134
+ filter = []
135
+
136
+ # filter = "tags:(tag1 AND tag2...)
137
+ if params.has_key?(:hashtags) and params[:hashtags].length > 0
138
+ filter << "tags:(#{params[:hashtags].map { |hashtag| "#{hashtag}" }.join(" AND ")})"
139
+ end
140
+
141
+ if params.has_key?(:origin)
142
+ # retrieve all the tweets from/to that user
143
+ if filter.empty?
144
+ filter = ""
145
+ else
146
+ filter = filter.join(' AND ')
147
+ end
148
+ if params[:origin].is_a?(String)
149
+ users = [params[:origin]]
150
+ else
151
+ users = params[:origin]
152
+ end
153
+
154
+ @base.post("channels/twitter",
155
+ {:uid => key,
156
+ :accounts => users.collect { |item| {:name => item} },
157
+ :filter => filter
158
+ })
159
+ else
160
+ # retrieve users mentions
161
+ users = params[:mentions]
162
+ locations = []
163
+ # create a stream per each origin
164
+ users.each { |user|
165
+ user_filter = filter.dup
166
+ user_filter << "recipients:#{user}"
167
+
168
+ locations << @base.post("channels/twitter",
169
+ {:uid => key,
170
+ :accounts => [{:name => user}],
171
+ :filter => "(#{user_filter.join(' AND ')})"
172
+ })
173
+ }
174
+ locations
175
+ end
176
+
177
+ end
178
+
179
+ ##
180
+ # Delete a Twitter channel
181
+ #
182
+ # ==== Parameters
183
+ # * +key+ twitter channel unique identifier
184
+ # === Return
185
+ # * nil if success
186
+ # * RestClient exception with relevant error information
187
+ def delete_twitter_channel(key)
188
+ @base.delete("channels/twitter/#{key}")
189
+ end
190
+
191
+ #
192
+ # Voice channel management
193
+ #
194
+ # Retrieve the voice channel
195
+ # @param voice Voice channel identifier. It it is not specified, all the voice channels are fetched
196
+ #
197
+ def get_voice_channel(voice = "")
198
+ data = @base.get("channels/voice/#{voice}")
199
+ data = ActiveSupport::JSON.decode(data)
200
+ Voice.unmarshal(data)
201
+ end
202
+
203
+ #
204
+ # Update the voice channel topic
205
+ # @param voice Voice channel identifier
206
+ # @param params
207
+ # String: topic new topic
208
+ # Hash:
209
+ # topic new topic
210
+ # welcome_message new welcome_message
211
+ # rejected_message new rejected_message
212
+ #
213
+ def update_voice_channel(voice, params)
214
+ attributes = {}
215
+ if params.is_a?(String)
216
+ attributes[:topic] = params
217
+ elsif params.is_a?(Hash)
218
+ Voice::UPDATE_ATTRIBUTES.each { |attr|
219
+ params.has_key?(attr) and attributes[attr] = params[attr]
220
+ }
221
+ else
222
+ # do nothing, raise exception...
223
+ end
224
+ @base.put("channels/voice/#{voice}", attributes)
225
+ end
226
+
227
+ ##
228
+ # Create a new voice channel
229
+ # ==== Parameters
230
+ # * +name+ voice channel identifier
231
+ # * +country+ country to allocate a DID
232
+ #
233
+ def create_voice_channel(name, country, privacy = Voice::Privacy::WHITELIST)
234
+ @base.post("channels/voice", {:uid => name, :country => country, :privacy => privacy})
235
+ end
236
+
237
+ ##
238
+ # Delete a voice channel
239
+ # ==== Parameters
240
+ # * +name+ voice channel identifier
241
+ #
242
+ def delete_voice_channel(voice)
243
+ @base.delete("channels/voice/#{voice}")
244
+ end
245
+
246
+ # Voice channel Phone Management
247
+
248
+ ##
249
+ # Retrieve a voice channel phone lists, that's the list of phones assigned to that voice channel
250
+ # ==== Parameters
251
+ # * +voice+ Voice channel identifier
252
+ # * +phone+ (optional) specific Phone number to retrieve. If it is not specified, all the list is fetched
253
+ def get_phones(voice, phone = "")
254
+ Phone.unmarshal(voice, ActiveSupport::JSON.decode(@base.get("channels/voice/#{voice}/phones/#{phone}")))
255
+ end
256
+
257
+ ##
258
+ # Delete one phone number or the whole phone list
259
+ # ==== Parameters
260
+ # * +voice+: Voice channel identifier
261
+ # * +phone+: specific number to delete.
262
+ def delete_phone(voice, phone)
263
+ @base.delete("channels/voice/#{voice}/phones/#{phone}")
264
+ end
265
+
266
+ ##
267
+ # Add a new phone number to the Voice channel
268
+ # ==== Parameters
269
+ # * +voice+: Voice channel identifier
270
+ # * +country+: for the phone number to be allocated
271
+ def add_phone(voice, country)
272
+ @base.post("channels/voice/#{voice}/phones", {:country => country})
273
+ end
274
+
275
+
276
+ ##
277
+ # Voice channel Whitelist management
278
+ #
279
+ # Retrieve the whitelist
280
+ # @param voice Voice channel identifier
281
+ # @param number (optional) specific whitelist number to retrieve. If it is not specified, all the list is fetched
282
+ def get_whitelist(voice, number = "")
283
+ if number.empty?
284
+ Whitelist.unmarshal(voice, ActiveSupport::JSON.decode(@base.get("channels/voice/#{voice}/whitelisted/#{number}")))
285
+ else
286
+ user = ActiveSupport::JSON.decode(@base.get("channels/voice/#{voice}/whitelisted/#{number}"))
287
+ WhitelistUser.new(*user.values)
288
+ end
289
+ end
290
+
291
+ #
292
+ # Delete one whitelist number or the whole whitelist
293
+ # @param voice Voice channel identifier
294
+ # @param number (optional) specific number to delete. If not present, the whole whitelist is deleted
295
+ def delete_whitelist(voice, number = "")
296
+ @base.delete("channels/voice/#{voice}/whitelisted/#{number}")
297
+ end
298
+
299
+ #
300
+ # Create a new item in the whitelist
301
+ # @param *args:
302
+ # - First parameter: voice channel identifier
303
+ # - Second parameter can be either:
304
+ # - WhitelistUser object with the name and phone information
305
+ # - two arguments name, phone
306
+ #
307
+ def add_whitelist(*args)
308
+
309
+ if args.length.eql?(2)
310
+ @base.post("channels/voice/#{args[0]}/whitelisted", {:name => args[1].name, :phone => args[1].phone})
311
+ else
312
+ @base.post("channels/voice/#{args[0]}/whitelisted", {:name => args[1], :phone => args[2]})
313
+ end
314
+
315
+ end
316
+
317
+ #
318
+ # Update a whitelist item
319
+ # @param *args:
320
+ # - First parameter: voice channel identifier
321
+ # - Second parameter can be either:
322
+ # - WhitelistUser object with the name and phone information
323
+ # - two arguments name, phone
324
+ #
325
+ def update_whitelist(*args)
326
+ if args.length.eql?(2)
327
+ @base.put("channels/voice/#{args[0]}/whitelisted/#{args[1].phone}", {:name => args[1].name})
328
+ else
329
+ @base.put("channels/voice/#{args[0]}/whitelisted/#{args[2]}", {:name => args[1]})
330
+ end
331
+ end
332
+
333
+ #
334
+ # RSS channel management
335
+ #
336
+ # Retrieve the rss channel
337
+ # @param name RSS channel identifier. It it is not specified, all the RSS channels are fetched
338
+ #
339
+ def get_rss_channel(name = "")
340
+ data = @base.get("channels/rss/#{name}")
341
+ data = ActiveSupport::JSON.decode(data)
342
+ Rss.unmarshal(data)
343
+ end
344
+
345
+ #
346
+ # Create a new rss channel
347
+ # @param name rss channel identifier
348
+ # @param uri RSS endpoint
349
+ #
350
+ def create_rss_channel(name, uri)
351
+ @base.post("channels/rss", {:uid => name, :uri => uri})
352
+ end
353
+
354
+ #
355
+ # Update the rss channel URI
356
+ # @param name RSS channel identifier
357
+ # @param uri new uri
358
+ #
359
+ def update_rss_channel(name, uri)
360
+ @base.put("channels/rss/#{name}", {:uri => uri})
361
+ end
362
+
363
+ #
364
+ # Delete a rss channel
365
+ # @param name rss channel identifier
366
+ #
367
+ def delete_rss_channel(name)
368
+ @base.delete("channels/rss/#{name}")
369
+ end
370
+
371
+ end
372
+
373
+ end
374
+ end