concerto_remote_video 0.3 → 0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0057c70e019b24d881176d1cee19c25b2cfbe15f
4
- data.tar.gz: 427ad38f5490bf3d9bb97b56613c9b6a90c9d884
3
+ metadata.gz: caf9e3fc8733e9ce4f3bf12f9106c12ec940bb19
4
+ data.tar.gz: 45a04bab69ebc87c2b0416853278d26f8607f455
5
5
  SHA512:
6
- metadata.gz: abf286284ce3481b42daac729849b5d71d41ab0274e2a72a97c558883c0a363a3bc7ddda0cb3e9bae14ef14c25d37f9e07cf123e435e838e777b10452d4cac83
7
- data.tar.gz: 6a21256b3c5f55af89a5be869f82c0ecd643c92291e78485e3aa3e8ae218990e7ff32a9c685c3fdbacfd4613d211deaf283e8aa444ac1585822164f2b9919912
6
+ metadata.gz: fc8385b9186679c85d221bddd20a4d3e94d4120ba91c983abbb4fd10b5ca3cc93014770fc9c7b9dd1c7b22cfe9caa9c0cc1a8d7c1794110a316471341d96f12a
7
+ data.tar.gz: 194518905108f1541db8f329ecdb7d6209f17530426e2e484ddb84bebe5bf32ef58ca008ac409045c23d5f8fe426553fb8d51295550a7a89a7aa97d34a51f89b
@@ -2,104 +2,110 @@ var initializedRemoteVideoHandlers = false;
2
2
  function initializeRemoteVideoHandlers() {
3
3
  if (!initializedRemoteVideoHandlers) {
4
4
 
5
- function getVideoInfo() {
6
- // need to know which vendor
7
- // will place title, description, duration into 'div.remote-video-info'
5
+ function getVideoPreview() {
6
+ var preview_url = '/concerto-remote-video/preview';
8
7
 
9
- var info = '<p>Video details could not be determined.</p>';
10
- var vendor = $('select#remote_video_config_video_vendor').val();
8
+ // Form video details
11
9
  var video_id = $('input#remote_video_config_video_id').val();
12
- var info_el = $('.remote-video-info');
13
- var preview_div = $('#preview_div');
14
- $(preview_div).empty();
10
+ var video_vendor = $('select#remote_video_config_video_vendor').val();
11
+
12
+ // Loading icon
13
+ if (video_id.length != 0) {
14
+ $(preview_div).empty().html('<i class=\"ficon-spinner icon-spin\"></i> searching...');
15
+ $('.remote-video-info').empty();
16
+ // Video preview request
17
+ $.ajax({
18
+ type: 'POST',
19
+ url: preview_url,
20
+ data: {
21
+ video_id: video_id,
22
+ video_vendor: video_vendor
23
+ },
24
+ success: function(data) {
25
+ loadVideoInfo(data);
26
+ loadVideoPreview(data);
27
+ },
28
+ error: function(e) {
29
+ loadVideoPreview({video_available: false});
30
+ }
31
+ });
32
+ }
33
+ }
15
34
 
16
- if (info_el.length != 0) {
17
- // we found the summary box
18
- if (typeof vendor != 'undefined') {
19
- // we found the vendor selection, call appropriate api
20
- if (vendor == 'YouTube') {
21
- $(info_el).empty().html('<i class=\"ficon-spinner icon-spin\"></i> searching...');
22
- // todo: dont search if video_id is empty
23
- $.ajax({
24
- url: '//gdata.youtube.com/feeds/api/videos?q='+ encodeURIComponent(video_id) +'&v=2&max-results=1&format=5&alt=jsonc',
25
- dataType: 'jsonp',
26
- timeout: 4000,
27
- success: function (data) {
28
- if (parseInt(data['data']['totalItems']) > 0) {
29
- // we got something, repoint data to first item in results
30
- data = data['data']['items'];
31
- $(info_el).empty().html('<img src="' + data[0].thumbnail.hqDefault + '"/><h4>' + data[0].title + '</h4><i>' + data[0].duration + ' secs</i><br/><p>' + data[0].description + '</p>');
32
- previewVideo(data[0].id);
33
- } else {
34
- $(info_el).empty().html(info);
35
- }
36
- },
37
- error: function (xoptions, textStatus) {
38
- $(info_el).empty().html(info);
39
- }
40
- });
41
- } else if (vendor == 'Vimeo') {
42
- $(info_el).empty().html('<i class=\"ficon-spinner icon-spin\"></i> searching...');
43
- $.ajax({
44
- url: '//vimeo.com/api/v2/video/' + encodeURIComponent(video_id) + '.json',
45
- dataType: 'jsonp',
46
- timeout: 4000,
47
- success: function (data) {
48
- if (data.length > 0) {
49
- // we got something
50
- $(info_el).empty().html('<img src="' + data[0].thumbnail_small + '"/><h4>' + data[0].title + '</h4><i>' + data[0].duration + ' secs</i><br/><p>' + data[0].description + '</p>');
51
- previewVideo();
52
- } else {
53
- $(info_el).empty().html(info);
54
- }
55
- },
56
- error: function (xoptions, textStatus) {
57
- $(info_el).empty().html(info);
58
- }
59
- });
60
- } else if (vendor == 'HTTPVideo') {
61
- $(info_el).empty();
62
- if (video_id != "")
63
- {
64
- previewVideo();
35
+ function loadVideoInfo(data) {
36
+ if (data['video_available']) {
37
+ // Target elements for setting video info
38
+ var info_el = $('.remote-video-info');
39
+ var name_el = $('input#remote_video_name');
40
+ var duration_el = $('input#remote_video_duration');
41
+ // Initialize info content
42
+ var title = '';
43
+ var description = '<p></p>';
44
+ var duration = '';
45
+ var vendor = data['video_vendor'];
46
+
47
+ if (vendor == 'HTTPVideo') {
48
+ $(info_el).empty();
49
+ return;
50
+ } else {
51
+ // YouTube no longer returns these details without an API key
52
+ if (vendor != 'YouTube') {
53
+ if (data['description']) {
54
+ // Preview video description
55
+ var description = '<p>' + data['description'] + '</p>';
56
+ }
57
+ if (data['title']) {
58
+ // Set content title to video returned title
59
+ name_el.val(data['title']);
60
+ }
61
+ if (data['duration']) {
62
+ // Set content duration to video duration
63
+ duration = '<i>' + data['duration'] + ' secs</i>';
64
+ duration_el.val(data['duration']);
65
65
  }
66
66
  }
67
- }
67
+ }
68
+
69
+ // Load video info
70
+ var info = '<img src="'+data['thumb_url']+'"/></h4>'+duration+'<br/>'+description;
71
+ $(info_el).empty().html(info);
68
72
  }
69
73
  }
70
74
 
71
- function previewVideo(video_id) {
72
- var url = $('input#remote_video_config_video_id').data('url');
73
- if (url) {
74
- if (video_id == null) {
75
- video_id = $('input#remote_video_config_video_id').val();
76
- }
77
- $("#preview_div").load(url, { data: {
78
- video_vendor: $('select#remote_video_config_video_vendor').val(),
79
- video_id: video_id,
80
- allow_flash: $('input#remote_video_config_allow_flash').val(),
81
- duration: $('input#remote_video_duration').val(),
82
- name: $('input#remote_video_name').val()
83
- }, type: 'RemoteVideo' });
75
+ function loadVideoPreview(data) {
76
+ var preview_el = $('#preview_div');
77
+ if (data['video_available']) {
78
+ $(preview_div).empty().html(data['preview_code']);
79
+ } else {
80
+ $(preview_div).empty();
84
81
  }
85
82
  }
86
83
 
87
84
  function updateTooltip() {
88
85
  var vendor = $('select#remote_video_config_video_vendor').val();
86
+ var hint_el = $('div#video_id_hint');
87
+ var id_el = $('input#remote_video_config_video_id');
88
+
89
89
  if (vendor == 'YouTube') {
90
- $('input#remote_video_config_video_id').attr("placeholder", "DGbqvYbPZBY");
91
- $('div#video_id_hint').html('Specify the video id or keywords');
90
+ id_el.attr('placeholder', 'DGbqvYbPZBY');
91
+ hint_el.html('Specify the exact YouTube video id');
92
92
  } else if (vendor == 'Vimeo') {
93
- $('input#remote_video_config_video_id').attr("placeholder", "4224811");
94
- $('div#video_id_hint').html('Specify the exact vimeo video id');
93
+ id_el.attr('placeholder', '4224811');
94
+ hint_el.html('Specify the exact vimeo video id');
95
95
  } else if (vendor == 'HTTPVideo') {
96
- $('input#remote_video_config_video_id').attr("placeholder", "http://media.w3.org/2010/05/sintel/trailer.mp4");
97
- $('div#video_id_hint').html('Specify the url of the video');
96
+ id_el.attr('placeholder', 'http://media.w3.org/2010/05/sintel/trailer.mp4');
97
+ hint_el.html('Specify the url of the video');
98
+ } else if (vendor == 'Wistia') {
99
+ id_el.attr('placeholder', 'g5pnf59ala');
100
+ hint_el.html('Specify the exact Wistia video id');
101
+ } else if (vendor == 'DailyMotion') {
102
+ id_el.attr('placeholder', 'x23shps');
103
+ hint_el.html('Specify the exact DailyMotion video id');
98
104
  }
99
105
  }
100
106
 
101
- $('input#remote_video_config_video_id').on('blur', getVideoInfo);
102
- $('select#remote_video_config_video_vendor').on('change', getVideoInfo);
107
+ $('input#remote_video_config_video_id').on('blur', getVideoPreview);
108
+ $('select#remote_video_config_video_vendor').on('change', getVideoPreview);
103
109
  $('select#remote_video_config_video_vendor').on('change', updateTooltip);
104
110
 
105
111
  initializedRemoteVideoHandlers = true;
@@ -107,4 +113,4 @@ function initializeRemoteVideoHandlers() {
107
113
  }
108
114
 
109
115
  $(document).ready(initializeRemoteVideoHandlers);
110
- $(document).on('page:change', initializeRemoteVideoHandlers);
116
+ $(document).on('page:change', initializeRemoteVideoHandlers);
@@ -1,4 +1,4 @@
1
1
  module ConcertoRemoteVideo
2
2
  class ApplicationController < ActionController::Base
3
3
  end
4
- end
4
+ end
@@ -0,0 +1,12 @@
1
+ module ConcertoRemoteVideo
2
+ class RemoteVideoController < ConcertoRemoteVideo::ApplicationController
3
+ def preview
4
+ @video_data = RemoteVideo.preview({
5
+ video_vendor: params[:video_vendor],
6
+ video_id: params[:video_id]
7
+ })
8
+
9
+ render json: @video_data
10
+ end
11
+ end
12
+ end
@@ -1,4 +1,4 @@
1
1
  module ConcertoRemoteVideo
2
2
  module ApplicationHelper
3
3
  end
4
- end
4
+ end
@@ -13,9 +13,11 @@ class RemoteVideo < Content
13
13
 
14
14
  DISPLAY_NAME = 'Video'
15
15
  VIDEO_VENDORS = {
16
- :HTTPVideo => { :id => "HTTPVideo", :name => "Video URL", :url => ""},
16
+ :HTTPVideo => { :id => "HTTPVideo", :name => "Self-hosted Video", :url => ""},
17
17
  :YouTube => { :id => "YouTube", :name => "YouTube", :url => "https://www.youtube.com/embed/" },
18
- :Vimeo => { :id => "Vimeo", :name => "Vimeo", :url => "https://player.vimeo.com/video/" }
18
+ :Vimeo => { :id => "Vimeo", :name => "Vimeo", :url => "https://player.vimeo.com/video/" },
19
+ :Wistia => { :id => "Wistia", :name => "Wistia", :url => "https://fast.wistia.net/embed/iframe/" },
20
+ :DailyMotion => { :id => "DailyMotion", :name => "DailyMotion", :url => "https://www.dailymotion.com/embed/video/" }
19
21
  }
20
22
 
21
23
  attr_accessor :config
@@ -56,111 +58,61 @@ class RemoteVideo < Content
56
58
 
57
59
  # Load some info about this video from YouTube.
58
60
  def load_info
61
+ require 'video_info'
62
+
59
63
  # dont abort if there is a duration specified
60
64
  return if self.config['video_id'].nil? #|| !self.duration.nil?
61
65
  return if !self.new_record?
62
-
63
- require 'net/http'
64
66
  if self.config['video_vendor'] == VIDEO_VENDORS[:YouTube][:id]
65
- begin
66
- video_id = URI.escape(self.config['video_id'])
67
- url = "http://gdata.youtube.com/feeds/api/videos?q=#{video_id}&v=2&max-results=1&format=5&alt=jsonc"
68
- json = Net::HTTP.get_response(URI.parse(url)).body
69
- data = ActiveSupport::JSON.decode(json)
70
- rescue MultiJson::ParseError => e
71
- Rails.logger.error("Could not parse results from YouTube @ #{url}: #{e.message}: #{json}")
72
- errors.add(:video_id, "Could not parse results from YouTube")
73
- return
74
- rescue
75
- Rails.logger.error("YouTube not reachable @ #{url}.")
76
- errors.add(:video_id, "Could not get information about video from YouTube")
77
- return
78
- end
79
- if data['data']['totalItems'].to_i <= 0
80
- Rails.logger.error('No video found from ' + url)
81
- self.config['video_id'] = ''
82
- return
83
- end
84
- return if data['data'].nil? || data['data']['items'].nil?
85
- video_data = data['data']['items'][0]
86
- self.config['video_id'] = video_data['id']
87
- self.duration = video_data['duration'].to_i
88
- self.config['thumb_url'] = video_data['thumbnail']['hqDefault']
89
- self.config['title'] = video_data['title']
90
- self.config['description'] = video_data['description']
67
+ video = VideoInfo.new("http://www.youtube.com/watch?v=#{URI.escape(self.config['video_id'])}")
91
68
  elsif self.config['video_vendor'] == VIDEO_VENDORS[:Vimeo][:id]
92
- data=[]
93
- begin
94
- video_id = URI.escape(self.config['video_id'])
95
- url = "http://vimeo.com/api/v2/video/#{video_id}.json"
96
- uri = URI.parse(url)
97
- http = Net::HTTP.new(uri.host, uri.port)
98
- request = Net::HTTP::Get.new(uri.request_uri)
99
- response = http.request(request)
100
- if response.code == '200' #ok
101
- json = response.body
102
- data = ActiveSupport::JSON.decode(json)
103
- end
104
- rescue => e
105
- Rails.logger.error("Could not get information about video from Vimeo @ #{url}: #{e.message}")
106
- config['video_id'] = ''
107
- return
108
- end
109
- if data.empty?
110
- Rails.logger.debug('No video found from ' + url)
111
- self.config['video_id'] = ''
112
- return
113
- end
114
- video_data = data[0]
115
- # some vimeo videos have zero for their duration, so in that case use what the user supplied
116
- self.duration = (video_data['duration'].to_i > 0 ? video_data['duration'].to_i : self.duration.to_i)
117
- self.config['thumb_url'] = video_data['thumbnail_small']
118
- self.config['title'] = video_data['title']
119
- self.config['description'] = video_data['description']
69
+ video = VideoInfo.new("http://vimeo.com/#{URI.escape(self.config['video_id'])}")
70
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:Wistia][:id]
71
+ video = VideoInfo.new("http://fast.wistia.com/embed/medias/#{URI.escape(self.config['video_id'])}")
72
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:DailyMotion][:id]
73
+ video = VideoInfo.new("http://dailymotion.com/video/#{URI.escape(self.config['video_id'])}")
120
74
  elsif self.config['video_vendor'] == VIDEO_VENDORS[:HTTPVideo][:id]
121
- self.config['thumb_url'] = ''
122
- self.config['title'] = self.name
123
- self.config['description'] = ''
124
- end
125
- end
126
-
127
- # Build a URL for an iframe player.
128
- def player_url(params={})
129
- url = VIDEO_VENDORS[self.config['video_vendor'].to_sym][:url] + self.config['video_id']
130
- if self.config['allow_flash'] == '0'
131
- params['html5'] = 1
75
+ # self hosted video, skip video info gem configuration below
76
+ self.config['preview_code'] = "<video preload controls width=\"100%\"><source src=\"#{self.config['video_id']}\" /></video>"
77
+ self.config['video_available'] = true
78
+ return
132
79
  end
133
- url += '?' + URI.escape(params.collect{|k,v| "#{k}=#{v}"}.join('&'))
134
- return url
135
- end
136
80
 
137
- def video_id_must_exist
138
- if config['video_id'].empty?
139
- errors.add(:video_id, 'could not be found')
140
- end
141
- end
142
-
143
- def video_vendor_supported
144
- if config['video_vendor'].empty? || !VIDEO_VENDORS.collect { |a,b| b[:id] }.include?(config['video_vendor'])
145
- errors.add(:video_vendor, 'must be ' + VIDEO_VENDORS.collect { |a,b| b[:id] }.join(" or "))
81
+ # Video info gem details
82
+ if !video.nil? and video.available?
83
+ # some vimeo videos have zero for their duration, so in that case use what the user supplied
84
+ self.duration = (video.duration.to_i > 0 ? video.duration.to_i : self.duration.to_i)
85
+ self.config['title'] = video.title
86
+ self.config['description'] = video.description
87
+ self.config['video_id'] = video.video_id
88
+ self.config['duration'] = video.duration
89
+ self.config['preview_url'] = video.embed_url
90
+ self.config['preview_code'] = video.embed_code
91
+ # set video thumbnail using video info or using YouTube image url to bypass API restrictions
92
+ if video.provider == VIDEO_VENDORS[:YouTube][:id]
93
+ self.config['thumb_url'] = "https://i.ytimg.com/vi/" + video.video_id + "/hqdefault.jpg"
94
+ else
95
+ self.config['thumb_url'] = video.thumbnail_large
96
+ end
146
97
  end
98
+ # Store video availablility to skip preview rendering
99
+ self.config['video_available'] = video.available?
147
100
  end
148
101
 
149
102
  def self.preview(data)
103
+ require 'video_info'
104
+
150
105
  begin
151
106
  o = RemoteVideo.new()
152
107
  o.config['video_id'] = data[:video_id]
153
108
  o.config['video_vendor'] = data[:video_vendor]
154
- o.config['allow_flash'] = data[:allow_flash]
155
- o.name = data[:name]
156
- o.duration = data[:duration]
109
+ o.load_info
157
110
 
158
- results = o.render_preview
159
111
  rescue => e
160
- results = "Unable to preview. #{e.message}"
112
+ return "Unable to preview. #{e.message}"
161
113
  end
162
114
 
163
- return results
115
+ return o.config
164
116
  end
165
117
 
166
118
  def preview
@@ -173,6 +125,28 @@ class RemoteVideo < Content
173
125
  return results
174
126
  end
175
127
 
128
+ # Build a URL for an iframe player.
129
+ def player_url(params={})
130
+ url = VIDEO_VENDORS[self.config['video_vendor'].to_sym][:url] + self.config['video_id']
131
+ if self.config['allow_flash'] == '0'
132
+ params['html5'] = 1
133
+ end
134
+ url += '?' + URI.escape(params.collect{|k,v| "#{k}=#{v}"}.join('&'))
135
+ return url
136
+ end
137
+
138
+ def video_id_must_exist
139
+ if config['video_id'].empty?
140
+ errors.add(:video_id, 'could not be found')
141
+ end
142
+ end
143
+
144
+ def video_vendor_supported
145
+ if config['video_vendor'].empty? || !VIDEO_VENDORS.collect { |a,b| b[:id] }.include?(config['video_vendor'])
146
+ errors.add(:video_vendor, 'must be ' + VIDEO_VENDORS.collect { |a,b| b[:id] }.join(" or "))
147
+ end
148
+ end
149
+
176
150
  def render_details
177
151
  if self.config['video_vendor'] == VIDEO_VENDORS[:YouTube][:id]
178
152
  settings = {
@@ -186,14 +160,30 @@ class RemoteVideo < Content
186
160
  }
187
161
  elsif self.config['video_vendor'] == VIDEO_VENDORS[:Vimeo][:id]
188
162
  settings = {
189
- :api => 1, # use Javascript API
190
- :player_id => 'playerv', #arbitrary id of iframe
191
- :byline => 0,
192
- :portrait => 0,
193
- :autoplay => 1
163
+ :api => 1, # use Javascript API
164
+ :player_id => 'playerv', #arbitrary id of iframe
165
+ :byline => 0, # Hide video byline
166
+ :badge => 0, # Hide vendor logo
167
+ :portrait => 0, # Don't show user's portrait
168
+ :autoplay => 1, # Autostart the video
169
+ :title => 0 # Hide video title
170
+ }
171
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:Wistia][:id]
172
+ settings = {
173
+ :autoPlay => true, # Autostart the video
174
+ :chromeless => true, # Don't show any controls
175
+ :playerColor => 'black' # Change player outlines to black
176
+ }
177
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:DailyMotion][:id]
178
+ settings = {
179
+ :autoplay => 1, # Autostart the video
180
+ :chromeless => 1, # Don't show any controls
181
+ :info => 0, # Hide video information
182
+ :logo => 0, # Hide vendor logo
183
+ :related => 0 # Don't show related videos at end
194
184
  }
195
185
  elsif self.config['video_vendor'] == VIDEO_VENDORS[:HTTPVideo][:id]
196
- settings = {
186
+ settings = {
197
187
  :autoplay => 1, # Autostart the video
198
188
  :end => self.duration, # Stop it around the duration
199
189
  :controls => 0, # Don't show any controls
@@ -203,11 +193,14 @@ class RemoteVideo < Content
203
193
  end
204
194
 
205
195
  def render_preview
206
- if self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:YouTube][:id] || self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:Vimeo][:id]
196
+ if self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:YouTube][:id] ||
197
+ self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:Vimeo][:id] ||
198
+ self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:Wistia][:id] ||
199
+ self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:DailyMotion][:id]
207
200
  player_settings = { :end => self.duration, :rel => 0, :theme => 'light', :iv_load_policy => 3 }
208
- results = "<iframe id=\"player\" type=\"text/html\" width=\"100%\" src=\"#{self.player_url(player_settings)}\" frameborder=\"0\"></iframe>"
201
+ results = self.config['preview_code']
209
202
  elsif self.config['video_vendor'] == RemoteVideo::VIDEO_VENDORS[:HTTPVideo][:id]
210
- results = "<video preload controls width=\"100%\"><source src=\"#{self.config['video_id']}\" /></video>"
203
+ results = self.config['preview_code']
211
204
  end
212
205
 
213
206
  results
@@ -0,0 +1,37 @@
1
+ <!--
2
+ The `concerto-remote-video` element provides embedded video.
3
+ @element concerto-content
4
+ @status alpha
5
+ -->
6
+ <polymer-element name="concerto-remote-video" attributes="path" constructor="ConcertoRemoteVideo" extends="concerto-content">
7
+ <template>
8
+ <style>
9
+ :host {
10
+ display: block;
11
+ width: 100%;
12
+ height: 100%;
13
+ }
14
+
15
+ :host(.core-transition) {
16
+ overflow: hidden;
17
+ }
18
+
19
+ #video {
20
+ width: 100%;
21
+ height: 100%;
22
+ }
23
+ </style>
24
+ <iframe id="video" frameBorder="0"></iframe>
25
+ </template>
26
+
27
+ <script>
28
+ Polymer({
29
+ domReady: function() {
30
+ this.$.video.src = this.path;
31
+ }
32
+ });
33
+ </script>
34
+ </polymer-element>
35
+ <script>
36
+ registerContentType("concerto-remote-video", "ConcertoRemoteVideo");
37
+ </script>
data/config/routes.rb CHANGED
@@ -1,3 +1,7 @@
1
1
  Rails.application.routes.draw do
2
2
  resources :remote_videos, :controller => :contents, :except => [:index, :show], :path => "content"
3
3
  end
4
+
5
+ ConcertoRemoteVideo::Engine.routes.draw do
6
+ post "preview", to: ConcertoRemoteVideo::RemoteVideoController.action(:preview)
7
+ end
@@ -5,5 +5,13 @@ module ConcertoRemoteVideo
5
5
  initializer "register content type" do |app|
6
6
  app.config.content_types << RemoteVideo
7
7
  end
8
+
9
+ # Define plugin information for the Concerto application to read
10
+ def plugin_info(plugin_info_class)
11
+ @plugin_info ||= plugin_info_class.new do
12
+ add_route("concerto-remote-video", ConcertoRemoteVideo::Engine)
13
+ add_view_hook "frontend/ScreensController", :concerto_frontend_plugins, partial: "frontend/concerto_remote_video.html"
14
+ end
15
+ end
8
16
  end
9
- end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module ConcertoRemoteVideo
2
- VERSION = "0.3"
2
+ VERSION = "0.4"
3
3
  end
@@ -1,4 +1,4 @@
1
1
  require "concerto_remote_video/engine"
2
2
 
3
3
  module ConcertoRemoteVideo
4
- end
4
+ end
metadata CHANGED
@@ -1,27 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerto_remote_video
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Michalski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-04 00:00:00.000000000 Z
11
+ date: 2015-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: video_info
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  description: Adds support for remotely hosted videos, like YouTube or vimeo, in Concerto
@@ -32,11 +46,15 @@ executables: []
32
46
  extensions: []
33
47
  extra_rdoc_files: []
34
48
  files:
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
35
52
  - app/assets/javascripts/concerto_remote_video/application.js
36
53
  - app/assets/javascripts/concerto_remote_video/remote_video.js
37
54
  - app/assets/stylesheets/concerto_remote_video/application.css
38
55
  - app/assets/stylesheets/concerto_remote_video/remote_video.css
39
56
  - app/controllers/concerto_remote_video/application_controller.rb
57
+ - app/controllers/concerto_remote_video/remote_video_controller.rb
40
58
  - app/helpers/concerto_remote_video/application_helper.rb
41
59
  - app/models/remote_video.rb
42
60
  - app/views/contents/remote_video/_form_middle.html.erb
@@ -45,22 +63,20 @@ files:
45
63
  - app/views/contents/remote_video/_render_grid.html.erb
46
64
  - app/views/contents/remote_video/_render_tile.html.erb
47
65
  - app/views/contents/remote_video/_tab_icon.html.erb
66
+ - app/views/frontend/_concerto_remote_video.html
48
67
  - config/routes.rb
68
+ - lib/concerto_remote_video.rb
49
69
  - lib/concerto_remote_video/engine.rb
50
70
  - lib/concerto_remote_video/version.rb
51
- - lib/concerto_remote_video.rb
52
- - lib/generators/concerto_remote_video/install_generator.rb
53
- - lib/tasks/concerto_remote_video_tasks.rake
54
- - public/frontend_js/contents/remote_video.js
55
- - LICENSE
56
- - Rakefile
57
- - README.md
58
71
  - test/concerto_remote_video_test.rb
72
+ - test/dummy/README.rdoc
73
+ - test/dummy/Rakefile
59
74
  - test/dummy/app/assets/javascripts/application.js
60
75
  - test/dummy/app/assets/stylesheets/application.css
61
76
  - test/dummy/app/controllers/application_controller.rb
62
77
  - test/dummy/app/helpers/application_helper.rb
63
78
  - test/dummy/app/views/layouts/application.html.erb
79
+ - test/dummy/config.ru
64
80
  - test/dummy/config/application.rb
65
81
  - test/dummy/config/boot.rb
66
82
  - test/dummy/config/database.yml
@@ -76,13 +92,10 @@ files:
76
92
  - test/dummy/config/initializers/wrap_parameters.rb
77
93
  - test/dummy/config/locales/en.yml
78
94
  - test/dummy/config/routes.rb
79
- - test/dummy/config.ru
80
95
  - test/dummy/public/404.html
81
96
  - test/dummy/public/422.html
82
97
  - test/dummy/public/500.html
83
98
  - test/dummy/public/favicon.ico
84
- - test/dummy/Rakefile
85
- - test/dummy/README.rdoc
86
99
  - test/dummy/script/rails
87
100
  - test/fixtures/concerto_remote_video/remote_videos.yml
88
101
  - test/integration/navigation_test.rb
@@ -98,17 +111,17 @@ require_paths:
98
111
  - lib
99
112
  required_ruby_version: !ruby/object:Gem::Requirement
100
113
  requirements:
101
- - - '>='
114
+ - - ">="
102
115
  - !ruby/object:Gem::Version
103
116
  version: '0'
104
117
  required_rubygems_version: !ruby/object:Gem::Requirement
105
118
  requirements:
106
- - - '>='
119
+ - - ">="
107
120
  - !ruby/object:Gem::Version
108
121
  version: '0'
109
122
  requirements: []
110
123
  rubyforge_project:
111
- rubygems_version: 2.0.14
124
+ rubygems_version: 2.2.2
112
125
  signing_key:
113
126
  specification_version: 4
114
127
  summary: Remotely hosted video for Concerto 2
@@ -1,31 +0,0 @@
1
- require 'rails/generators'
2
-
3
- module ConcertoRemoteVideo
4
- class InstallGenerator < Rails::Generators::Base
5
- source_root File.expand_path('../../../../', __FILE__)
6
-
7
- desc 'Copy the RemoteVideo JavaScript to the frontend and register it.'
8
-
9
- def install
10
- copy_js
11
- register
12
- recompile
13
- end
14
-
15
- private
16
- def copy_js
17
- copy_file 'public/frontend_js/contents/remote_video.js', 'public/frontend_js/contents/remote_video.js'
18
- end
19
-
20
- def register
21
- append_file 'public/frontend_js/content_types.js', "goog.require('concerto.frontend.Content.RemoteVideo');\n"
22
- end
23
-
24
- def recompile
25
- inside 'public/frontend_js' do
26
- run('/bin/bash compile.sh', {:verbose => true})
27
- end
28
- end
29
-
30
- end
31
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :concerto_remote_video do
3
- # # Task goes here
4
- # end
@@ -1,97 +0,0 @@
1
- goog.provide('concerto.frontend.Content.RemoteVideo');
2
-
3
- goog.require('concerto.frontend.Content');
4
- goog.require('concerto.frontend.ContentTypeRegistry');
5
- goog.require('goog.Uri');
6
- goog.require('goog.dom');
7
- goog.require('goog.events');
8
- goog.require('goog.events.EventType');
9
- goog.require('goog.style');
10
-
11
-
12
-
13
- /**
14
- * Remote Video.
15
- *
16
- * @param {Object} data Properties for this piece of content.
17
- * @constructor
18
- * @extends {concerto.frontend.Content}
19
- */
20
- concerto.frontend.Content.RemoteVideo = function(data) {
21
- concerto.frontend.Content.call(this, data);
22
-
23
- /**
24
- * The height of the field the image is being shown in.
25
- * @type {number}
26
- * @private
27
- */
28
- this.field_height_ = parseFloat(data['field']['size']['height']);
29
-
30
- /**
31
- * The width of the field the image is being shown in.
32
- * @type {number}
33
- * @private
34
- */
35
- this.field_width_ = parseFloat(data['field']['size']['width']);
36
-
37
- /**
38
- * The iframe being displayed.
39
- * @type {Object}
40
- */
41
- this.iframe = null;
42
-
43
- /**
44
- * The URL for the video / iframe.
45
- * @type {string}
46
- */
47
- this.video_url = data['render_details']['path'];
48
-
49
- /**
50
- * Extra parameters to include in the URL.
51
- * @type {?string}
52
- * @private
53
- */
54
- this.url_parms_ = (data['field']['config'] ? data['field']['config']['url_parms'] : null);
55
- if (goog.isDefAndNotNull(this.url_parms_)) {
56
- this.url_parms_ = this.url_parms_.trim();
57
- if (goog.string.startsWith(this.url_parms_, '?'))
58
- this.url_parms_ = goog.string.remove(this.url_parms_, '?');
59
- if (goog.string.startsWith(this.url_parms_, '&'))
60
- this.url_parms_ = goog.string.remove(this.url_parms_, '&');
61
- if (goog.string.contains(this.video_url, '?')) {
62
- this.url_parms_ = '&' + this.url_parms_;
63
- } else {
64
- this.url_parms_ = '?' + this.url_parms_;
65
- }
66
- } else {
67
- this.url_parms_ = '';
68
- }
69
-
70
- /**
71
- * Bump the duration of this content by 1 second.
72
- * This attempts to account for 1 second of load time and should be
73
- * improved in the future.
74
- */
75
- this.duration = this.duration + 1;
76
- };
77
- goog.inherits(concerto.frontend.Content.RemoteVideo, concerto.frontend.Content);
78
-
79
- // Register the content type.
80
- concerto.frontend.ContentTypeRegistry['RemoteVideo'] =
81
- concerto.frontend.Content.RemoteVideo;
82
-
83
-
84
- /**
85
- * Build the embed iframe and signal that we're ready to use it.
86
- * @private
87
- */
88
- concerto.frontend.Content.RemoteVideo.prototype.load_ = function() {
89
- this.iframe = goog.dom.createElement('iframe');
90
- this.iframe.src = this.video_url + this.url_parms_;
91
- this.iframe.frameborder = 0;
92
- goog.style.setSize(this.iframe, '100%', '100%');
93
- goog.style.setSize(this.div_, '100%', '100%');
94
- goog.style.setStyle(this.iframe, 'border', 0);
95
- goog.dom.appendChild(this.div_, this.iframe);
96
- this.finishLoad();
97
- };