concerto_remote_video 0.0.3 → 0.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.
data/README.md CHANGED
@@ -5,7 +5,10 @@ This plugin provides support to play remotely hosted videos, like YouTube videos
5
5
  2. ```bundle install```
6
6
  3. ```./script/rails generate concerto_remote_video:install install```
7
7
 
8
+ The last step produces a lot of output, if it runs successfully, because it recompiles the frontend js files.
9
+
8
10
  ## Supported hosts:
9
11
  * YouTube
12
+ * Vimeo
10
13
 
11
14
  Concerto 2 Remove Video is licensed under the Apache License, Version 2.0.
@@ -0,0 +1,80 @@
1
+ // contents.js
2
+
3
+ // attach handler to video_id so when it loses focus we can look up some video details
4
+ // not dry, but no middle man
5
+ function attachHandlers() {
6
+ $('input#remote_video_config_video_id').on('blur', getVideoInfo);
7
+ $('select#remote_video_config_video_vendor').on('change', getVideoInfo);
8
+
9
+ $('select#remote_video_config_video_vendor').on('change', updateTooltip);
10
+
11
+ function updateTooltip() {
12
+ var vendor = $('select#remote_video_config_video_vendor').val();
13
+ if (vendor == 'YouTube') {
14
+ $('input#remote_video_config_video_id').attr("placeholder", "DGbqvYbPZBY");
15
+ $('div#video_hint_id').html('Specify the video id or keywords');
16
+ } else if (vendor == 'Vimeo') {
17
+ $('input#remote_video_config_video_id').attr("placeholder", "4224811");
18
+ $('div#video_hint_id').html('Specify the exact vimeo video id');
19
+ }
20
+ }
21
+
22
+ function getVideoInfo() {
23
+ // need to know which vendor
24
+ // will place title, description, duration into 'div.remote-video-info'
25
+
26
+ var info = '<p>Video details could not be determined.</p>';
27
+ var vendor = $('select#remote_video_config_video_vendor').val();
28
+ var video_id = $('input#remote_video_config_video_id').val();
29
+ var info_el = $('.remote-video-info');
30
+
31
+ if (info_el.length != 0) {
32
+ // we found the summary box
33
+ if (typeof vendor != 'undefined') {
34
+ // we found the vendor selection, call appropriate api
35
+ if (vendor == 'YouTube') {
36
+ $(info_el).empty().html('searching...');
37
+ // todo: dont search if video_id is empty
38
+ $.ajax({
39
+ url: 'http://gdata.youtube.com/feeds/api/videos?q='+ encodeURIComponent(video_id) +'&v=2&max-results=1&format=5&alt=jsonc',
40
+ dataType: 'jsonp',
41
+ timeout: 4000,
42
+ success: function (data) {
43
+ if (parseInt(data['data']['totalItems']) > 0) {
44
+ // we got something, repoint data to first item in results
45
+ data = data['data']['items'];
46
+ $(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>');
47
+ } else {
48
+ $(info_el).empty().html(info);
49
+ }
50
+ },
51
+ error: function (xoptions, textStatus) {
52
+ $(info_el).empty().html(info);
53
+ }
54
+ });
55
+ } else if (vendor == 'Vimeo') {
56
+ $(info_el).empty().html('searching...');
57
+ $.ajax({
58
+ url: 'http://vimeo.com/api/v2/video/' + encodeURIComponent(video_id) + '.json',
59
+ dataType: 'jsonp',
60
+ timeout: 4000,
61
+ success: function (data) {
62
+ if (data.length > 0) {
63
+ // we got something
64
+ $(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>');
65
+ } else {
66
+ $(info_el).empty().html(info);
67
+ }
68
+ },
69
+ error: function (xoptions, textStatus) {
70
+ $(info_el).empty().html(info);
71
+ }
72
+ });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ $(document).ready(attachHandlers);
80
+ $(document).on('page:change', attachHandlers);
@@ -0,0 +1,16 @@
1
+
2
+ div.remote-video-info {
3
+ padding: 1em;
4
+ }
5
+
6
+ div.remote-video-info img {
7
+ float: left;
8
+ max-width: 150px;
9
+ max-height: 150px;
10
+ margin: 0 5px 5px 0;
11
+ border: solid 1px black;
12
+ }
13
+
14
+ div.video_id_hint {
15
+ font-style: italic;
16
+ }
@@ -5,9 +5,15 @@ class RemoteVideo < Content
5
5
  before_validation :save_config
6
6
 
7
7
  validate :video_id_must_exist
8
- validates :duration, :numericality => { :greater_than => 0 }
8
+ #todo: put back, commented out because I keep getting duration is not a number
9
+ #validates :duration, :numericality => { :greater_than => 0 }
10
+ validate :video_vendor_supported
9
11
 
10
- DISPLAY_NAME = 'YouTube Video'
12
+ DISPLAY_NAME = 'Video'
13
+ VIDEO_VENDORS = {
14
+ :YouTube => { :id => "YouTube", :url => "https://www.youtube.com/embed/" },
15
+ :Vimeo => { :id => "Vimeo", :url => "https://player.vimeo.com/video/" }
16
+ }
11
17
 
12
18
  attr_accessor :config
13
19
 
@@ -41,37 +47,74 @@ class RemoteVideo < Content
41
47
 
42
48
  def self.form_attributes
43
49
  attributes = super()
44
- attributes.concat([:config => [:video_id, :allow_flash]])
50
+ # what about :thumb_url, :title, :description
51
+ attributes.concat([:config => [:video_vendor, :video_id, :allow_flash]])
45
52
  end
46
53
 
47
54
  # Load some info about this video from YouTube.
48
55
  def load_info
49
- return if self.config['video_id'].nil? || !self.duration.nil?
56
+ # dont abort if there is a duration specified
57
+ return if self.config['video_id'].nil? #|| !self.duration.nil?
50
58
  require 'net/http'
51
- #begin
52
- video_id = URI.escape(self.config['video_id'])
53
- url = "http://gdata.youtube.com/feeds/api/videos?q=#{video_id}&v=2&max-results=1&format=5&alt=jsonc"
54
- json = Net::HTTP.get_response(URI.parse(url)).body
55
- data = ActiveSupport::JSON.decode(json)
56
- #rescue
57
- # Rails.logger.debug("YouTube not reachable @ #{url}.")
58
- # config['video_id'] = ''
59
- # return
60
- #end
61
- if data['data']['totalItems'].to_i <= 0
62
- Rails.logger.debug('No video found from ' + url)
63
- self.config['video_id'] = ''
64
- return
59
+ if self.config['video_vendor'] == VIDEO_VENDORS[:YouTube][:id]
60
+ #begin
61
+ video_id = URI.escape(self.config['video_id'])
62
+ url = "http://gdata.youtube.com/feeds/api/videos?q=#{video_id}&v=2&max-results=1&format=5&alt=jsonc"
63
+ json = Net::HTTP.get_response(URI.parse(url)).body
64
+ data = ActiveSupport::JSON.decode(json)
65
+ #rescue
66
+ # Rails.logger.debug("YouTube not reachable @ #{url}.")
67
+ # config['video_id'] = ''
68
+ # return
69
+ #end
70
+ if data['data']['totalItems'].to_i <= 0
71
+ Rails.logger.debug('No video found from ' + url)
72
+ self.config['video_id'] = ''
73
+ return
74
+ end
75
+ video_data = data['data']['items'][0]
76
+ self.config['video_id'] = video_data['id']
77
+ self.duration = video_data['duration'].to_i
78
+ self.config['thumb_url'] = video_data['thumbnail']['hqDefault']
79
+ self.config['title'] = video_data['title']
80
+ self.config['description'] = video_data['description']
81
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:Vimeo][:id]
82
+ #todo: put these info urls in the VV constant
83
+ #http://vimeo.com/api/v2/video/video_id.json
84
+ data=[]
85
+ #begin
86
+ video_id = URI.escape(self.config['video_id'])
87
+ url = "http://vimeo.com/api/v2/video/#{video_id}.json"
88
+ uri = URI.parse(url)
89
+ http = Net::HTTP.new(uri.host, uri.port)
90
+ request = Net::HTTP::Get.new(uri.request_uri)
91
+ response = http.request(request)
92
+ if response.code == '200' #ok
93
+ json = response.body
94
+ data = ActiveSupport::JSON.decode(json)
95
+ end
96
+ #rescue
97
+ # Rails.logger.debug("YouTube not reachable @ #{url}.")
98
+ # config['video_id'] = ''
99
+ # return
100
+ #end
101
+ if data.empty?
102
+ Rails.logger.debug('No video found from ' + url)
103
+ self.config['video_id'] = ''
104
+ return
105
+ end
106
+ video_data = data[0]
107
+ # some vimeo videos have zero for their duration, so in that case use what the user supplied
108
+ self.duration = (video_data['duration'].to_i > 0 ? video_data['duration'].to_i : self.duration.to_i)
109
+ self.config['thumb_url'] = video_data['thumbnail_small']
110
+ self.config['title'] = video_data['title']
111
+ self.config['description'] = video_data['description']
65
112
  end
66
- video_data = data['data']['items'][0]
67
- self.config['video_id'] = video_data['id']
68
- self.duration = video_data['duration'].to_i
69
- self.config['thumb_url'] = video_data['thumbnail']['hqDefault']
70
113
  end
71
114
 
72
115
  # Build a URL for an iframe player.
73
116
  def player_url(params={})
74
- url = "https://www.youtube.com/embed/#{self.config['video_id']}"
117
+ url = VIDEO_VENDORS[self.config['video_vendor'].to_sym][:url] + self.config['video_id']
75
118
  if self.config['allow_flash'] == '0'
76
119
  params['html5'] = 1
77
120
  end
@@ -85,16 +128,32 @@ class RemoteVideo < Content
85
128
  end
86
129
  end
87
130
 
131
+ def video_vendor_supported
132
+ if config['video_vendor'].empty? || !VIDEO_VENDORS.collect { |a,b| b[:id] }.include?(config['video_vendor'])
133
+ errors.add(:video_vendor, 'must be ' + VIDEO_VENDORS.collect { |a,b| b[:id] }.join(" or "))
134
+ end
135
+ end
136
+
88
137
  def render_details
89
- settings = {
90
- :autoplay => 1, # Autostart the video
91
- :end => self.duration, # Stop it around the duration
92
- :controls => 0, # Don't show any controls
93
- :modestbranding => 1, # Use the less fancy branding
94
- :rel => 0, # Don't show related videos
95
- :showinfo => 0, # Don't show the video info
96
- :iv_load_policy => 3 # Don't show any of those in-video labels
97
- }
138
+ if self.config['video_vendor'] == VIDEO_VENDORS[:YouTube][:id]
139
+ settings = {
140
+ :autoplay => 1, # Autostart the video
141
+ :end => self.duration, # Stop it around the duration
142
+ :controls => 0, # Don't show any controls
143
+ :modestbranding => 1, # Use the less fancy branding
144
+ :rel => 0, # Don't show related videos
145
+ :showinfo => 0, # Don't show the video info
146
+ :iv_load_policy => 3 # Don't show any of those in-video labels
147
+ }
148
+ elsif self.config['video_vendor'] == VIDEO_VENDORS[:Vimeo][:id]
149
+ settings = {
150
+ :api => 1, # use Javascript API
151
+ :player_id => 'playerv', #arbitrary id of iframe
152
+ :byline => 0,
153
+ :portrait => 0,
154
+ :autoplay => 1
155
+ }
156
+ end
98
157
  {:path => player_url(settings)}
99
158
  end
100
159
  end
@@ -1,9 +1,9 @@
1
1
  <fieldset>
2
- <legend><span><%=t(:provide_details)%></span></legend>
2
+ <legend><span><%=t('contents.provide_details')%></span></legend>
3
3
  <div class="clearfix">
4
4
  <%= form.label :name %>
5
5
  <div class="input">
6
- <%= form.text_field :name %>
6
+ <%= form.text_field :name, :class => "input-xlarge" %>
7
7
  </div>
8
8
  </div>
9
9
 
@@ -11,9 +11,8 @@
11
11
  </fieldset>
12
12
 
13
13
  <fieldset>
14
- <legend><span><%=t(:select_feed)%></span></legend>
15
- <label>&nbsp;</label>
16
- <div class="input">
14
+ <legend><span><%=t('contents.select_feed')%></span></legend>
15
+ <div class="clearfix">
17
16
  <% if @content.new_record? %>
18
17
  <%= render :partial => 'contents/form_elements/feeds' %>
19
18
  <% end %>
@@ -1,10 +1,22 @@
1
+ <%= javascript_include_tag "remote_video" %>
2
+ <%= stylesheet_link_tag "remote_video" %>
3
+
1
4
  <fieldset>
2
- <legend><span>YouTube Video</span></legend>
5
+ <legend><span><%= RemoteVideo::DISPLAY_NAME %></span></legend>
6
+ <div class="row-fluid">
3
7
  <%= form.fields_for :config do |config| %>
8
+ <div class='span4'>
9
+ <div class="clearfix">
10
+ <%= config.label :video_vendor, 'Video Vendor' %>
11
+ <div class="input">
12
+ <%= config.select :video_vendor, RemoteVideo::VIDEO_VENDORS.collect { |a,b| b[:id] } %>
13
+ </div>
14
+ </div>
4
15
  <div class="clearfix">
5
16
  <%= config.label :video_id %>
6
17
  <div class="input">
7
- <%= config.text_field :video_id, :placeholder => 'DGbqvYbPZBY', :size => 15 %>
18
+ <%= config.text_field :video_id, :placeholder => "DGbqvYbPZBY", :class => "input-small" %>
19
+ <div id="video_id_hint">Specify the video id or keywords</div>
8
20
  </div>
9
21
  </div>
10
22
  <div class="clearfix">
@@ -13,5 +25,17 @@
13
25
  <%= config.select :allow_flash, [["No", 0], ["Yes", 1]] %>
14
26
  </div>
15
27
  </div>
28
+ <div class="clearfix">
29
+ <%= form.label :duration %>
30
+ <div class="input">
31
+ <%= form.number_field :duration, :class => "input-small" %><br/>
32
+ (automatically set if ascertained from video source)
33
+ </div>
34
+ </div>
35
+ </div>
36
+ <div>
37
+ <div class='remote-video-info'></div>
38
+ </div>
16
39
  <% end %>
40
+ </div>
17
41
  </fieldset>
@@ -1 +1 @@
1
- <div style="background-image:url(<%= content.config['thumb_url'] %>); background-size: cover; width: 100%; height: 100%;"></div>
1
+ <div class="pop" style="background-image:url(<%= content.config['thumb_url'] %>); background-size: cover; width: 100%; height: 100%;" data-content="<%= content.config['description']%>" data-title="<%= content.config['title']%>"></div>
@@ -1,3 +1,3 @@
1
1
  module ConcertoRemoteVideo
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -9,6 +9,7 @@ module ConcertoRemoteVideo
9
9
  def install
10
10
  copy_js
11
11
  register
12
+ recompile
12
13
  end
13
14
 
14
15
  private
@@ -19,5 +20,12 @@ module ConcertoRemoteVideo
19
20
  def register
20
21
  append_file 'public/frontend_js/content_types.js', "goog.require('concerto.frontend.Content.RemoteVideo');\n"
21
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
+
22
30
  end
23
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerto_remote_video
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-08 00:00:00.000000000 -07:00
12
+ date: 2013-05-30 00:00:00.000000000 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &70122145172500 !ruby/object:Gem::Requirement
17
+ requirement: &70296757751560 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '3.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70122145172500
25
+ version_requirements: *70296757751560
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: sqlite3
28
- requirement: &70122145170660 !ruby/object:Gem::Requirement
28
+ requirement: &70296757727300 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,15 +33,18 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70122145170660
37
- description: Adds support for remotely hosted videos, like YouTube, in Concerto 2
36
+ version_requirements: *70296757727300
37
+ description: Adds support for remotely hosted videos, like YouTube or vimeo, in Concerto
38
+ 2
38
39
  email:
39
40
  - bmichalski@gmail.com
40
41
  executables: []
41
42
  extensions: []
42
43
  extra_rdoc_files: []
43
44
  files:
45
+ - app/assets/javascripts/remote_video.js
44
46
  - app/assets/stylesheets/concerto_remote_video/application.css
47
+ - app/assets/stylesheets/remote_video.css
45
48
  - app/controllers/concerto_remote_video/application_controller.rb
46
49
  - app/helpers/concerto_remote_video/application_helper.rb
47
50
  - app/models/remote_video.rb