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,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