concerto_remote_video 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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
- };