canvas_connect 0.0.2 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .rvmrc
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
@@ -17,6 +17,7 @@
17
17
  #
18
18
 
19
19
  class AdobeConnectConference < WebConference
20
+
20
21
  # Public: Start a new conference and return its key. (required by WebConference)
21
22
  #
22
23
  # Returns a conference key string.
@@ -50,8 +51,14 @@ class AdobeConnectConference < WebConference
50
51
  # Returns a meeting URL string.
51
52
  def admin_join_url(admin, _ = nil)
52
53
  user = add_host(admin)
53
- key = CanvasConnect::Service.user_session(user, config[:domain])
54
- "#{meeting_url}?session=#{key}"
54
+ connect_settings = {
55
+ :username => user.username,
56
+ :password => user.password,
57
+ :domain => CanvasConnect.config[:domain]
58
+ }
59
+ ac_service = AdobeConnect::Service.new(connect_settings)
60
+ ac_service.log_in
61
+ "#{meeting_url}?session=#{ac_session.session}"
55
62
  end
56
63
 
57
64
  # Public: Add a participant to the conference and create a meeting URL.
@@ -89,7 +96,7 @@ class AdobeConnectConference < WebConference
89
96
  #
90
97
  # Returns the CanvasConnect::ConnectUser.
91
98
  def add_host(user)
92
- connect_user = CanvasConnect::ConnectUser.find_or_create(user)
99
+ connect_user = AdobeConnect::User.find(user) || AdobeConnect::User.create(user)
93
100
  connect_service.permissions_update(
94
101
  :acl_id => find_conference_key,
95
102
  :principal_id => connect_user.id,
@@ -115,7 +122,7 @@ class AdobeConnectConference < WebConference
115
122
  Rails.logger.error "Adobe Connect error on meeting create. Field: #{error['field']}, Value: #{error['subcode']}"
116
123
 
117
124
  if error['field'] == 'folder-id'
118
- throw CanvasConnect::MeetingFolderError.new("Folder '#{CanvasConnect.config[:meeting_container]}' doesn't exist!")
125
+ raise CanvasConnect::MeetingFolderError.new("Folder '#{config[:meeting_container]}' doesn't exist!")
119
126
  end
120
127
 
121
128
  return nil
@@ -144,10 +151,38 @@ class AdobeConnectConference < WebConference
144
151
  result.body.xpath('//status[@code="ok"]').present?
145
152
  end
146
153
 
154
+ def meeting_name
155
+ @cached_meeting_name ||= generate_meeting_name
156
+ end
157
+
158
+ def meeting_url
159
+ @cached_meeting_url ||= generate_meeting_url
160
+ end
161
+
162
+ def meeting_url_suffix
163
+ @cached_meeting_url_suffix ||= generate_meeting_url_suffix
164
+ end
165
+
166
+ # Internal: Get and cache a reference to the remote folder.
167
+ #
168
+ # Returns a CanvasConnect::MeetingFolder.
169
+ def meeting_folder
170
+ @meeting_folder ||= AdobeConnect::MeetingFolder.find(config[:meeting_container], CanvasConnect.client)
171
+ end
172
+
173
+ # Internal: Manage a connection to an Adobe Connect API.
174
+ #
175
+ # Returns a CanvasConnect::Service object.
176
+ def connect_service
177
+ CanvasConnect.client
178
+ end
179
+
180
+ private
181
+
147
182
  # Internal: Create a unique meeting name from the course and conference IDs.
148
183
  #
149
184
  # Returns a meeting name string.
150
- def meeting_name
185
+ def generate_meeting_name
151
186
  course_code = if self.context.respond_to?(:course_code)
152
187
  self.context.course_code
153
188
  elsif self.context.context.respond_to?(:course_code)
@@ -157,34 +192,17 @@ class AdobeConnectConference < WebConference
157
192
  end
158
193
  "#{course_code}: #{self.title} [#{self.id}]"
159
194
  end
160
- memoize :meeting_name
161
195
 
162
196
  # Internal: Generate the base URL for the meeting.
163
- def meeting_url
197
+ def generate_meeting_url
164
198
  "#{config[:domain]}/#{meeting_url_suffix}"
165
199
  end
166
- memoize :meeting_url
167
200
 
168
201
  # Internal: Generate a URL suffix for this conference.
169
202
  #
170
203
  # Returns a URL suffix string of format "canvas-meeting-:id".
171
- def meeting_url_suffix
204
+ def generate_meeting_url_suffix
172
205
  "canvas-meeting-#{self.id}"
173
206
  end
174
- memoize :meeting_url_suffix
175
-
176
- # Internal: Get and cache a reference to the remote folder.
177
- #
178
- # Returns a CanvasConnect::MeetingFolder.
179
- def meeting_folder
180
- @meeting_folder ||= CanvasConnect::MeetingFolder.new(config[:meeting_container])
181
- end
182
-
183
- # Internal: Manage a connection to an Adobe Connect API.
184
- #
185
- # Returns a CanvasConnect::Service object.
186
- def connect_service
187
- CanvasConnect.client
188
- end
189
207
  end
190
208
 
@@ -16,5 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = %w{app lib}
19
+
20
+ gem.add_dependency 'rake', '>= 0.9.6'
21
+ gem.add_dependency 'adobe_connect', '>= 0.0.6'
19
22
  end
20
23
 
@@ -30,6 +30,7 @@ module Canvas
30
30
  #
31
31
  # Returns false on error or a hash of settings options.
32
32
  def self.validate(settings, plugin_setting)
33
+ settings.stringify_keys!
33
34
  filtered_settings = settings.slice(*REQUIRED_KEYS)
34
35
  if all_empty?(filtered_settings)
35
36
  # Allow no settings.
@@ -16,13 +16,11 @@
16
16
  # with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #
18
18
 
19
+ require 'adobe_connect'
20
+
19
21
  require_dependency "canvas_connect/version"
20
22
  require_dependency "canvas/plugins/validators/adobe_connect_validator"
21
23
  require_dependency "canvas/plugins/adobe_connect"
22
- require_dependency "canvas_connect/response"
23
- require_dependency "canvas_connect/meeting_folder"
24
- require_dependency "canvas_connect/connect_user"
25
- require_dependency "canvas_connect/service"
26
24
 
27
25
  module CanvasConnect
28
26
  class ConnectionError < StandardError; end
@@ -38,7 +36,7 @@ module CanvasConnect
38
36
  ApplicationController.view_paths.unshift(view_path)
39
37
  end
40
38
 
41
- require_dependency "models/adobe_connect_conference"
39
+ require_dependency File.expand_path("./../app/models/adobe_connect_conference", File.dirname(__FILE__))
42
40
 
43
41
  Canvas::Plugins::AdobeConnect.new
44
42
  end
@@ -48,15 +46,27 @@ module CanvasConnect
48
46
  #
49
47
  # Returns a settings hash.
50
48
  def self.config
51
- Canvas::Plugin.find('adobe_connect').settings || {}
49
+ settings = Canvas::Plugin.find('adobe_connect').settings || {}
50
+ AdobeConnect::Config.declare do
51
+ username settings[:login]
52
+ password settings[:password_dec]
53
+ domain settings[:domain]
54
+ end
55
+ settings
52
56
  end
53
57
 
54
58
  # Return a cached Connect Service object to make requests with.
55
59
  #
56
- # Returns a CanvasConnect::Service.
60
+ # Returns a AdobeConnect::Service.
57
61
  def self.client
58
62
  unless @client
59
- @client = Service.new(*self.config.values_at(:login, :password_dec, :domain))
63
+ settings = self.config
64
+ connect_settings = {
65
+ :username => settings[:login],
66
+ :password => settings[:password_dec],
67
+ :domain => settings[:domain]
68
+ }
69
+ @client = AdobeConnect::Service.new(connect_settings)
60
70
  @client.log_in
61
71
  end
62
72
 
@@ -1,22 +1,3 @@
1
- #
2
- # Copyright (C) 2012 Instructure, Inc.
3
- #
4
- # This file is part of Canvas.
5
- #
6
- # Canvas is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Affero General Public License as published by the Free
8
- # Software Foundation, version 3 of the License.
9
- #
10
- # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
- # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
- # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
- # details.
14
- #
15
- # You should have received a copy of the GNU Affero General Public License along
16
- # with this program. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
-
19
1
  module CanvasConnect
20
- VERSION = "0.0.2"
2
+ VERSION = '0.0.5'
21
3
  end
22
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-21 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-02-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.6
30
+ - !ruby/object:Gem::Dependency
31
+ name: adobe_connect
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.0.6
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.0.6
14
46
  description: Canvas Connect is an Adobe Connect plugin for the Instructure Canvas
15
47
  LMS. It allows teachers and administrators to create and launch Connect conferences
16
48
  directly from their courses.
@@ -31,10 +63,6 @@ files:
31
63
  - lib/canvas/plugins/adobe_connect.rb
32
64
  - lib/canvas/plugins/validators/adobe_connect_validator.rb
33
65
  - lib/canvas_connect.rb
34
- - lib/canvas_connect/connect_user.rb
35
- - lib/canvas_connect/meeting_folder.rb
36
- - lib/canvas_connect/response.rb
37
- - lib/canvas_connect/service.rb
38
66
  - lib/canvas_connect/version.rb
39
67
  - spec_canvas/lib/canvas/plugins/validators/adobe_connect_validator_spec.rb
40
68
  - spec_canvas/lib/canvas_connect/response_spec.rb
@@ -61,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
89
  version: '0'
62
90
  requirements: []
63
91
  rubyforge_project:
64
- rubygems_version: 1.8.23
92
+ rubygems_version: 1.8.25
65
93
  signing_key:
66
94
  specification_version: 3
67
95
  summary: Adobe Connect integration for Instructure Canvas (http://instructure.com).
@@ -1,105 +0,0 @@
1
- #
2
- # Copyright (C) 2012 Instructure, Inc.
3
- #
4
- # This file is part of Canvas.
5
- #
6
- # Canvas is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Affero General Public License as published by the Free
8
- # Software Foundation, version 3 of the License.
9
- #
10
- # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
- # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
- # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
- # details.
14
- #
15
- # You should have received a copy of the GNU Affero General Public License along
16
- # with this program. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
-
19
- module CanvasConnect
20
- class ConnectUser
21
- attr_accessor :id, :canvas_user
22
- attr_reader :client
23
-
24
- # Public: Create a new ConnectUser instance.
25
- #
26
- # canvas_user - A Canvas User object.
27
- # client - A CanvasConnect::Service instance. (default: CanvasConnect.client)
28
- def initialize(canvas_user, client = CanvasConnect.client)
29
- @canvas_user, @client = [canvas_user, client]
30
- end
31
-
32
- # Public: Save this user to the Adobe Connect instance.
33
- #
34
- # Returns true.
35
- def save
36
- response = @client.principal_update(
37
- :first_name => @canvas_user.first_name.present? ? @canvas_user.first_name : 'Unknown',
38
- :last_name => @canvas_user.last_name.present? ? @canvas_user.last_name : 'Unknown',
39
- :login => username,
40
- :password => password,
41
- :type => 'user',
42
- :has_children => 0,
43
- :email => @canvas_user.email)
44
- @id = response.at_xpath('//principal')['principal-id']
45
- true
46
- end
47
-
48
- # Public: Generate a unique Adobe Connect username for this user.
49
- #
50
- # Examples
51
- #
52
- # connect_user.username #=> canvas_user_15
53
- #
54
- # Returns a username string.
55
- def username
56
- @canvas_user.email
57
- end
58
-
59
- # Internal: Generate a 10 character password for Adobe Connect.
60
- #
61
- # Returns a password string.
62
- def password
63
- @password ||= Digest::SHA1.hexdigest(@canvas_user.uuid)[0..9]
64
- end
65
-
66
- class << self
67
- # Public: Find a Canvas user on an Adobe Connect instance.
68
- #
69
- # user - A Canvas user object.
70
- #
71
- # Returns a CanvasConnect::ConnectUser or nil.
72
- def find(user)
73
- connect_user = ConnectUser.new(user)
74
- response = connect_user.client.principal_list(:filter_login => connect_user.username)
75
- if found_user = response.at_xpath('//principal')
76
- connect_user.id = found_user['principal-id']
77
- connect_user
78
- else
79
- nil
80
- end
81
- end
82
-
83
- # Public: Create an Adobe Connect user for the given Canvas user.
84
- #
85
- # user - The Canvas user to create in Connect.
86
- #
87
- # Returns a new CanvasConnect::ConnectUser.
88
- def create(user)
89
- new_user = ConnectUser.new(user)
90
- new_user.save
91
-
92
- new_user
93
- end
94
-
95
- # Public: Find the given user in Connect or, if they don't exist, create them.
96
- #
97
- # user - A Canvas user.
98
- #
99
- # Returns a CanvasConnect::ConnectUser.
100
- def find_or_create(user)
101
- find(user) || create(user)
102
- end
103
- end
104
- end
105
- end
@@ -1,60 +0,0 @@
1
- #
2
- # Copyright (C) 2012 Instructure, Inc.
3
- #
4
- # This file is part of Canvas.
5
- #
6
- # Canvas is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Affero General Public License as published by the Free
8
- # Software Foundation, version 3 of the License.
9
- #
10
- # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
- # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
- # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
- # details.
14
- #
15
- # You should have received a copy of the GNU Affero General Public License along
16
- # with this program. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
-
19
- module CanvasConnect
20
- class MeetingFolder
21
- attr_accessor :name
22
-
23
- extend ActiveSupport::Memoizable
24
-
25
- # Public: Create a new MeetingFolder.
26
- #
27
- # name - The name of the folder on Adobe Connect (must already exist).
28
- # client - A CanvasConnect::Service to make requests with. (default: CanvasConnect.client)
29
- def initialize(name, client = CanvasConnect.client)
30
- @name = name
31
- @client = client
32
- end
33
-
34
- # Public: Get the SCO ID for this folder.
35
- #
36
- # Returns an SCO ID string or nil if it doesn't exist.
37
- def id
38
- container = @client.sco_shortcuts.at_xpath('//sco[@type="user-meetings"]')
39
- remote_folder = @client.sco_expanded_contents(:sco_id => container['sco-id'],
40
- :filter_name => @name)
41
-
42
- remote_folder.at_xpath('//sco')['sco-id']
43
- rescue NoMethodError
44
- # Return nil if the container or remote_folder can't be found.
45
- nil
46
- end
47
- memoize :id
48
-
49
- # Public: Get the URL path for this folder.
50
- #
51
- # Returns a URL fragment string or nil if it can't be queried.
52
- def url_path
53
- response = @client.sco_info(:sco_id => @id)
54
- response.at_xpath('//url-path').text
55
- rescue NoMethodError
56
- nil
57
- end
58
- memoize :url_path
59
- end
60
- end
@@ -1,29 +0,0 @@
1
- #
2
- # Copyright (C) 2012 Instructure, Inc.
3
- #
4
- # This file is part of Canvas.
5
- #
6
- # Canvas is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Affero General Public License as published by the Free
8
- # Software Foundation, version 3 of the License.
9
- #
10
- # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
- # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
- # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
- # details.
14
- #
15
- # You should have received a copy of the GNU Affero General Public License along
16
- # with this program. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
-
19
- module CanvasConnect
20
- class Response < SimpleDelegator
21
- attr_reader :status, :headers, :body
22
-
23
- def initialize(status, headers, body)
24
- @status, @headers, @body = [status.to_i, headers, Nokogiri::XML(body)]
25
- super(@body)
26
- end
27
- end
28
- end
29
-
@@ -1,138 +0,0 @@
1
- #
2
- # Copyright (C) 2012 Instructure, Inc.
3
- #
4
- # This file is part of Canvas.
5
- #
6
- # Canvas is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Affero General Public License as published by the Free
8
- # Software Foundation, version 3 of the License.
9
- #
10
- # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
- # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
- # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
- # details.
14
- #
15
- # You should have received a copy of the GNU Affero General Public License along
16
- # with this program. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
-
19
- module CanvasConnect
20
- class Service
21
- attr_reader :username, :domain, :is_authenticated
22
-
23
- def initialize(username, password, domain)
24
- @username, @password, @domain = [username, password, domain]
25
- end
26
-
27
- # Public: Authenticate against the Adobe Connect server.
28
- #
29
- # Returns true.
30
- def log_in
31
- unless logged_in?
32
- response = login(:login => @username, :password => @password)
33
- if response.xpath('//status[@code="ok"]').empty?
34
- raise ConnectionError.new("Could not log in to #{@domain} as #{@username}.")
35
- end
36
-
37
- @is_authenticated = true
38
- end
39
-
40
- true
41
- end
42
-
43
- # Public: Determine if the current session is authenticated.
44
- #
45
- # Returns a boolean.
46
- def logged_in?
47
- @is_authenticated
48
- end
49
-
50
- # Public: Proxy any unknown methods to the Adobe Connect API.
51
- #
52
- # method - The snake-cased name of an Adobe Connect method, e.g. `common_info`.
53
- # args - Two optional arguments: a hash of GET params, and a skip_session boolean.
54
- #
55
- # Returns a CanvasConnect::Response.
56
- def method_missing(method, *args)
57
- action = "#{method}".dasherize
58
- params, skip_session = args
59
- params ||= {}
60
-
61
- request(action, params, !skip_session)
62
- end
63
-
64
- # Public: Create a new Connect session for the given user.
65
- #
66
- # user - A CanvasConnect::ConnectUser.
67
- # domain - The domain to authenticate against.
68
- def self.user_session(user, domain)
69
- service = CanvasConnect::Service.new(user.username, user.password, domain)
70
- service.log_in
71
-
72
- service.session_key
73
- end
74
-
75
- # Public: Get a session token for future requests.
76
- #
77
- # Returns a session token.
78
- def session_key
79
- unless @session_key
80
- response = request('common-info', {}, false)
81
- @session_key = response.xpath('//cookie').text
82
- end
83
-
84
- @session_key
85
- end
86
-
87
- protected
88
- # Internal: Create and/or return a Net::HTTP instance.
89
- #
90
- # Returns a Net::HTTP instance.
91
- def client
92
- unless @client
93
- uri = URI.parse(@domain)
94
- @client = Net::HTTP.new(uri.host, uri.port)
95
- @client.use_ssl = (uri.scheme == 'https')
96
- end
97
-
98
- @client
99
- end
100
-
101
- # Internal: Make a request to the Adobe Connect API.
102
- #
103
- # action - The name of the Connect API action to call.
104
- # params - A hash of parameters to pass with the request. (default: {})
105
- # with_session - If true, make the request inside a new or existing session. (default: true)
106
- #
107
- # Returns a CanvasConnect::Response object.
108
- def request(action, params = {}, with_session = true)
109
- params[:session] = session_key if with_session
110
- response = client.get("/api/xml?action=#{action}#{format_params(params)}")
111
-
112
- CanvasConnect::Response.new(response.code, response.each_header { |h| }, response.body)
113
- rescue SocketError, TimeoutError => e
114
- # Return an empty, timed-out request.
115
- Rails.logger.error "Adobe Connect Request Error on #{action}: #{e.message}"
116
- CanvasConnect::Response.new(408, {}, '')
117
- end
118
-
119
- # Internal: Convert snake-cased hash keys to dashed.
120
- #
121
- # params - A hash of parameters with snake-cased string or symbol keys.
122
- #
123
- # Examples
124
- #
125
- # format_params({param_name: 'value', other_param: 'value 2'})
126
- #
127
- # # Returns "&param-name=value&other-param=value%202"
128
- #
129
- # Returns a query string prefixed with a '&' (because it assumes action will be included).
130
- def format_params(params)
131
- params.inject(['']) do |arr, p|
132
- key, value = p
133
- arr << "#{key.to_s.dasherize}=#{URI.escape(value.to_s)}"
134
- end.join('&')
135
- end
136
- end
137
- end
138
-