diff --git a/app/views/content_viewer/_article_toolbar.html.erb b/app/views/content_viewer/_article_toolbar.html.erb index b371e22..2c19d80 100644 --- a/app/views/content_viewer/_article_toolbar.html.erb +++ b/app/views/content_viewer/_article_toolbar.html.erb @@ -1,7 +1,6 @@ >
- <% if @page.allow_edit?(user) && !remove_content_button(:edit) %> <% content = content_tag('span', label_for_edit_article(@page)) %> <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }) %> @@ -52,8 +51,10 @@ <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %> <% end %> + <%#*Adds extra buttons to the toolbar%> + <%= @plugins.dispatch(:article_extra_toolbar_buttons, @page).collect { |content| instance_exec(&content) }.join("") %> + <%= report_abuse(profile, :link, @page) %> -
<% if @page.blog? and !@page.image.nil? %> diff --git a/lib/contacts b/lib/contacts deleted file mode 120000 index e3c7a2b..0000000 --- a/lib/contacts +++ /dev/null @@ -1 +0,0 @@ -../vendor/cardmagic-contacts-f66219e6589ccaf3ab9e3574fdd41225d0dd5073/lib/contacts \ No newline at end of file diff --git a/lib/gdata b/lib/gdata deleted file mode 120000 index 16cb450..0000000 --- a/lib/gdata +++ /dev/null @@ -1 +0,0 @@ -../vendor/gdata-1.1.1/lib/gdata \ No newline at end of file diff --git a/lib/noosfero/plugin.rb b/lib/noosfero/plugin.rb index 3bc34e9..91ca00d 100644 --- a/lib/noosfero/plugin.rb +++ b/lib/noosfero/plugin.rb @@ -487,6 +487,12 @@ class Noosfero::Plugin nil end + # -> Adds adicional content to article toolbar buttons + # returns = lambda block that creates html code + def article_extra_toolbar_buttons(article) + nil + end + # -> Adds adicional content to article header # returns = lambda block that creates html code def article_header_extra_contents(article) diff --git a/plugins/video/lib/ext/article.rb b/plugins/video/lib/ext/article.rb new file mode 100644 index 0000000..2367bf3 --- /dev/null +++ b/plugins/video/lib/ext/article.rb @@ -0,0 +1,13 @@ +require_dependency 'article' + +class Article + + def self.folder_types_with_video + self.folder_types_without_video << 'VideoGallery' + end + + class << self + alias_method_chain :folder_types, :video + end + +end diff --git a/plugins/video/lib/video.rb b/plugins/video/lib/video.rb new file mode 100644 index 0000000..e9eed07 --- /dev/null +++ b/plugins/video/lib/video.rb @@ -0,0 +1,168 @@ +require 'noosfero/translatable_content' +require 'application_helper' +require 'net/http' + +# a base class for all text article types. +class Video < Article + + settings_items :video_url, :type => :string, :default => 'http://' + settings_items :video_width, :type => :integer, :default => 499 + settings_items :video_height, :type => :integer, :default => 353 + #youtube, vimeo, file + settings_items :video_provider, :type => :string + settings_items :video_format, :type => :string + settings_items :video_id, :type => :string + settings_items :video_thumbnail_url, :type => :string, :default => '/plugins/video/images/video_generic_thumbnail.jpg' + settings_items :video_thumbnail_width, :type=> :integer + settings_items :video_thumbnail_height, :type=> :integer + settings_items :video_duration, :type=> :integer, :default => 0 + + attr_accessible :video_url + + before_save :detect_video + + def self.type_name + _('Video') + end + + def can_display_versions? + true + end + + def self.short_description + _('Embedded Video') + end + + def self.description + _('Display embedded videos.') + end + + include ActionView::Helpers::TagHelper + def to_html(options={}) + article = self + proc do + render :file => 'content_viewer/video', :locals => {:article => article} + end + end + + def fitted_width + 499 + end + + def fitted_height + ((fitted_width * self.video_height) / self.video_width).to_i + end + + def thumbnail_fitted_width + 80 + end + + def thumbnail_fitted_height + ((thumbnail_fitted_width * self.video_thumbnail_height) / self.video_thumbnail_width).to_i + end + + def no_browser_support_message + '

To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video

' + end + + private + + YOUTUBE_ID_FORMAT = '\w-' + + def detect_video + if is_youtube? + self.video_provider = 'youtube' + self.video_id = extract_youtube_id + url = "http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch?v%3D#{self.video_id}&format=json" + resp = Net::HTTP.get_response(URI.parse(url)) + buffer = resp.body + vid = JSON.parse(buffer) + self.video_thumbnail_url = vid['thumbnail_url'] + self.video_width = vid['width'] + self.video_height = vid['height'] + self.video_thumbnail_width = vid['thumbnail_width'] + self.video_thumbnail_height = vid['thumbnail_height'] + url = "http://gdata.youtube.com/feeds/api/videos/#{self.video_id}?alt=json"; + resp = Net::HTTP.get_response(URI.parse(url)) + buffer = resp.body + vid = JSON.parse(buffer) + self.video_duration = vid['entry']['media$group']['media$content'][0]['duration'] + elsif is_vimeo? + self.video_provider = 'vimeo' + self.video_id = extract_vimeo_id + url = "http://vimeo.com/api/v2/video/#{self.video_id}.json" + resp = Net::HTTP.get_response(URI.parse(url)) + buffer = resp.body + vid = JSON.parse(buffer) + vid = vid[0] + #raise vid.to_yaml + self.video_thumbnail_url = vid['thumbnail_large'] + self.video_width = vid['width'] + self.video_height = vid['height'] + self.video_thumbnail_width = 640 + self.video_thumbnail_height = 360 + elsif true + self.video_format = detect_format + self.video_provider = 'file' + end + end + + def detect_format + video_type = 'video/unknown' + if /.mp4/i =~ self.video_url or /.mov/i =~ self.video_url + video_type='video/mp4' + elsif /.webm/i =~ self.video_url + video_type='video/webm' + elsif /.og[vg]/i =~ self.video_url + video_type='video/ogg' + end + video_type + end + + def is_youtube? + video_url.match(/.*(youtube.com.*v=[#{YOUTUBE_ID_FORMAT}]+|youtu.be\/[#{YOUTUBE_ID_FORMAT}]+).*/) ? true : false + end + + def is_vimeo? + video_url.match(/^(http[s]?:\/\/)?(www.)?(vimeo.com|player.vimeo.com\/video)\/([A-z]|\/)*[[:digit:]]+/) ? true : false + end + + def is_video_file? + video_url.match(/\.(mp4|ogg|ogv|webm)/) ? true : false + end + + def extract_youtube_id + return nil unless is_youtube? + youtube_match = video_url.match("v=([#{YOUTUBE_ID_FORMAT}]*)") + youtube_match ||= video_url.match("youtu.be\/([#{YOUTUBE_ID_FORMAT}]*)") + youtube_match[1] unless youtube_match.nil? + end + + def extract_vimeo_id + return nil unless is_vimeo? + vimeo_match = video_url.match('([[:digit:]]*)$') + vimeo_match[1] unless vimeo_match.nil? + end +end + +#To be used for the duration +#function formatSecondsAsTime(secs) { +# var hr = Math.floor(secs / 3600); +# var min = Math.floor((secs - (hr * 3600)) / 60); +# var sec = Math.floor(secs - (hr * 3600) - (min * 60)); +# +# if (hr < 10) { +# hr = "0" + hr; +# } +# if (min < 10) { +# min = "0" + min; +# } +# if (sec < 10) { +# sec = "0" + sec; +# } +# if (hr) { +# hr = "00"; +# } +# +# return hr + ':' + min + ':' + sec; +#} \ No newline at end of file diff --git a/plugins/video/lib/video_gallery.rb b/plugins/video/lib/video_gallery.rb new file mode 100644 index 0000000..f97db5a --- /dev/null +++ b/plugins/video/lib/video_gallery.rb @@ -0,0 +1,63 @@ +class VideoGallery < Folder + + def self.type_name + _('Video Gallery') + end + + settings_items :thumbnail_width, :type => :integer, :default => 50 + settings_items :thumbnail_height, :type => :integer, :default => 50 + settings_items :videos_per_row, :type => :integer, :default => 5 + + validate :not_belong_to_blog + + def not_belong_to_blog + errors.add(:parent, "A video gallery should not belong to a blog.") if parent && parent.blog? + end + + acts_as_having_settings :field => :setting + + xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation' + + include WhiteListFilter + filter_iframes :body + def iframe_whitelist + profile && profile.environment && profile.environment.trusted_sites_for_iframe + end + + def self.short_description + _('Video Gallery') + end + + def self.description + _('A gallery of link to videos that are hosted elsewhere.') + end + + include ActionView::Helpers::TagHelper + def to_html(options = {}) + video_gallery = self + proc do + render :file => 'content_viewer/video_gallery', :locals => {:video_gallery => video_gallery} + end + end + + def video_gallery? + true + end + + def can_display_hits? + false + end + + def accept_comments? + false + end + + def self.icon_name(article = nil) + 'Video gallery' + end + + def news(limit = 30, highlight = false) + profile.recent_documents(limit, ["articles.type != ? AND articles.highlighted = ? AND articles.parent_id = ?", 'Folder', highlight, id]) + end + +end diff --git a/plugins/video/lib/video_plugin.rb b/plugins/video/lib/video_plugin.rb index e3b0a4d..1c40743 100644 --- a/plugins/video/lib/video_plugin.rb +++ b/plugins/video/lib/video_plugin.rb @@ -1,9 +1,11 @@ require_dependency File.dirname(__FILE__) + '/video_block' +require_dependency File.dirname(__FILE__) + '/video' +require_dependency File.dirname(__FILE__) + '/video_gallery' class VideoPlugin < Noosfero::Plugin def self.plugin_name - "Video Block Plugin" + "Video Content type, Video Block and Video Gallery Plugin" end def self.plugin_description @@ -11,9 +13,42 @@ class VideoPlugin < Noosfero::Plugin end def self.extra_blocks - { + { VideoBlock => {} - } + } + end + + def stylesheet? + true + end + + def content_types + [VideoPlugin::VideoGallery, VideoPlugin::Video] + end + + def content_remove_new(content) + if content.kind_of?(VideoPlugin::VideoGallery) or content.kind_of?(VideoPlugin::Video) + true + end end + def content_remove_upload(content) + if content.kind_of?(VideoPlugin::VideoGallery) or content.kind_of?(VideoPlugin::Video) + true + end + end + + def article_extra_toolbar_buttons(content) + if content.kind_of?(VideoPlugin::VideoGallery) + proc do + content_tag('a', _("New Video"), + { :id=>"new-video-btn", + :class=>"button with-text icon-new", + :href=>url_for(:action => 'new', :type=>'Video', :controller=>'cms'), + :title=>_("New Video") + }) + end + end + end + end diff --git a/plugins/video/public/images/video_generic_thumbnail.jpg b/plugins/video/public/images/video_generic_thumbnail.jpg new file mode 100644 index 0000000..3069cbd Binary files /dev/null and b/plugins/video/public/images/video_generic_thumbnail.jpg differ diff --git a/plugins/video/public/javascripts/videojs/vjs.vimeo.js b/plugins/video/public/javascripts/videojs/vjs.vimeo.js new file mode 100644 index 0000000..8fe797d --- /dev/null +++ b/plugins/video/public/javascripts/videojs/vjs.vimeo.js @@ -0,0 +1,15 @@ +var VimeoState={UNSTARTED:-1,ENDED:0,PLAYING:1,PAUSED:2,BUFFERING:3}; +videojs.Vimeo=videojs.MediaTechController.extend({init:function(a,d,e){videojs.MediaTechController.call(this,a,d,e);this.player_=a;this.player_el_=document.getElementById(this.player_.id());this.player_.controls(!1);this.id_=this.player_.id()+"_vimeo_api";this.el_=videojs.Component.prototype.createEl("iframe",{id:this.id_,className:"vjs-tech",scrolling:"no",marginWidth:0,marginHeight:0,frameBorder:0,webkitAllowFullScreen:"true",mozallowfullscreen:"true",allowFullScreen:"true"});this.player_el_.insertBefore(this.el_, +this.player_el_.firstChild);this.baseUrl="https"==document.location.protocol?"https://secure.vimeo.com/video/":"http://player.vimeo.com/video/";this.vimeo={};this.vimeoInfo={};var h=this;this.el_.onload=function(){h.onLoad()};this.startMuted=a.options().muted;this.src(a.options().src)}});videojs.Vimeo.prototype.dispose=function(){this.vimeo.api("unload");delete this.vimeo;this.el_.parentNode.removeChild(this.el_);videojs.MediaTechController.prototype.dispose.call(this)}; +videojs.Vimeo.prototype.src=function(a){this.isReady_=!1;if(a=a.match(/^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)/))this.videoId=a[5];a={api:1,byline:0,portrait:0,show_title:0,show_byline:0,show_portait:0,fullscreen:1,player_id:this.id_,autoplay:this.player_.options().autoplay?1:0,loop:this.player_.options().loop?1:0};this.el_.src=this.baseUrl+this.videoId+"?"+videojs.Vimeo.makeQueryString(a)};videojs.Vimeo.prototype.load=function(){}; +videojs.Vimeo.prototype.play=function(){this.vimeo.api("play")};videojs.Vimeo.prototype.pause=function(){this.vimeo.api("pause")};videojs.Vimeo.prototype.paused=function(){return this.lastState!==VimeoState.PLAYING&&this.lastState!==VimeoState.BUFFERING};videojs.Vimeo.prototype.currentTime=function(){return this.vimeoInfo.time||0};videojs.Vimeo.prototype.setCurrentTime=function(a){this.vimeo.api("seekTo",a);this.player_.trigger("timeupdate")}; +videojs.Vimeo.prototype.duration=function(){return this.vimeoInfo.duration||0};videojs.Vimeo.prototype.buffered=function(){return videojs.createTimeRange(0,this.vimeoInfo.buffered||0)};videojs.Vimeo.prototype.volume=function(){return this.vimeoInfo.muted?this.vimeoInfo.muteVolume:this.vimeoInfo.volume};videojs.Vimeo.prototype.setVolume=function(a){this.vimeo.api("setvolume",a);this.vimeoInfo.volume=a;this.player_.trigger("volumechange")}; +videojs.Vimeo.prototype.muted=function(){return this.vimeoInfo.muted||!1};videojs.Vimeo.prototype.setMuted=function(a){a?(this.vimeoInfo.muteVolume=this.vimeoInfo.volume,this.setVolume(0)):this.setVolume(this.vimeoInfo.muteVolume);this.vimeoInfo.muted=a;this.player_.trigger("volumechange")};videojs.Vimeo.prototype.onReady=function(){this.isReady_=!0;this.triggerReady();this.startMuted&&(this.setMuted(!0),this.startMuted=!1)}; +videojs.Vimeo.prototype.onLoad=function(){this.vimeo.api&&(this.vimeo.api("unload"),delete this.vimeo);this.vimeo=$f(this.el_);this.vimeoInfo={state:VimeoState.UNSTARTED,volume:1,muted:!1,muteVolume:1,time:0,duration:0,buffered:0,url:this.baseUrl+this.videoId,error:null};var a=this;this.vimeo.addEvent("ready",function(d){a.onReady()});this.vimeo.addEvent("loadProgress",function(d,e){a.onLoadProgress(d)});this.vimeo.addEvent("playProgress",function(d,e){a.onPlayProgress(d)});this.vimeo.addEvent("play", +function(d){a.onPlay()});this.vimeo.addEvent("pause",function(d){a.onPause()});this.vimeo.addEvent("finish",function(d){a.onFinish()});this.vimeo.addEvent("seek",function(d,e){a.onSeek(d)})};videojs.Vimeo.prototype.onLoadProgress=function(a){var d=!this.vimeoInfo.duration;this.vimeoInfo.duration=a.duration;this.vimeoInfo.buffered=a.percent;this.player_.trigger("progress");d&&this.player_.trigger("durationchange")};videojs.Vimeo.prototype.onPlayProgress=function(a){this.vimeoInfo.time=a.seconds;this.player_.trigger("timeupdate")}; +videojs.Vimeo.prototype.onPlay=function(){this.vimeoInfo.state=VimeoState.PLAYING;this.player_.trigger("play")};videojs.Vimeo.prototype.onPause=function(){this.vimeoInfo.state=VimeoState.PAUSED;this.player_.trigger("pause")};videojs.Vimeo.prototype.onFinish=function(){this.vimeoInfo.state=VimeoState.ENDED;this.player_.trigger("ended")};videojs.Vimeo.prototype.onSeek=function(a){this.vimeoInfo.time=a.seconds;this.player_.trigger("timeupdate");this.player_.trigger("seeked")}; +videojs.Vimeo.prototype.onError=function(a){this.player_.error=a;this.player_.trigger("error")};videojs.Vimeo.isSupported=function(){return!0};videojs.Vimeo.prototype.supportsFullScreen=function(){return!1};videojs.Vimeo.canPlaySource=function(a){return"video/vimeo"==a.type};videojs.Vimeo.makeQueryString=function(a){var d=[],e;for(e in a)a.hasOwnProperty(e)&&d.push(encodeURIComponent(e)+"="+encodeURIComponent(a[e]));return d.join("&")}; +var Froogaloop=function(){function a(m){return new a.fn.init(m)}function d(a,c,b){if(!b.contentWindow.postMessage)return!1;var d=b.getAttribute("src").split("?")[0];a=JSON.stringify({method:a,value:c});"//"===d.substr(0,2)&&(d=window.location.protocol+d);b.contentWindow.postMessage(a,d)}function e(a){var c,b;try{c=JSON.parse(a.data),b=c.event||c.method}catch(d){}"ready"!=b||k||(k=!0);if(a.origin!=l)return!1;a=c.value;var e=c.data,g=""===g?null:c.player_id;c=g?f[g][b]:f[b];b=[];if(!c)return!1;void 0!== +a&&b.push(a);e&&b.push(e);g&&b.push(g);return 0b)c+=a[b];else break;2>b&&(c+="/")}l=c;return this},api:function(a,c){if(!this.element|| +!a)return!1;var b=this.element,e=""!==b.id?b.id:null,f=c&&c.constructor&&c.call&&c.apply?null:c,g=c&&c.constructor&&c.call&&c.apply?c:null;g&&h(a,g,e);d(a,f,b);return this},addEvent:function(a,c){if(!this.element)return!1;var b=this.element,e=""!==b.id?b.id:null;h(a,c,e);"ready"!=a?d("addEventListener",a,b):"ready"==a&&k&&c.call(null,e);return this},removeEvent:function(a){if(!this.element)return!1;var c=this.element,b=""!==c.id?c.id:null;a:{if(b&&f[b]){if(!f[b][a]){b=!1;break a}f[b][a]=null}else{if(!f[a]){b= +!1;break a}f[a]=null}b=!0}"ready"!=a&&b&&d("removeEventListener",a,c)}};a.fn.init.prototype=a.fn;window.addEventListener?window.addEventListener("message",e,!1):window.attachEvent("onmessage",e);return window.Froogaloop=window.$f=a}(); \ No newline at end of file diff --git a/plugins/video/public/javascripts/videojs/vjs.youtube.js b/plugins/video/public/javascripts/videojs/vjs.youtube.js new file mode 100644 index 0000000..4c29da0 --- /dev/null +++ b/plugins/video/public/javascripts/videojs/vjs.youtube.js @@ -0,0 +1 @@ +!function(){function addEventListener(element,event,cb){element.addEventListener?element.addEventListener(event,cb,!0):element.attachEvent(event,cb)}function setInnerText(element,text){if("undefined"==typeof element)return!1;var textProperty="innerText"in element?"innerText":"textContent";try{element[textProperty]=text}catch(anException){element.setAttribute("innerText",text)}}videojs.Youtube=videojs.MediaTechController.extend({init:function(player,options,ready){if(this.features.progressEvents=!1,this.features.timeupdateEvents=!1,videojs.MediaTechController.call(this,player,options,ready),this.isIos=/(iPad|iPhone|iPod)/g.test(navigator.userAgent),this.isAndroid=/(Android)/g.test(navigator.userAgent),this.playVideoIsAllowed=!(this.isIos||this.isAndroid),"undefined"!=typeof options.source)for(var key in options.source)options.source.hasOwnProperty(key)&&(player.options()[key]=options.source[key]);this.userQuality=videojs.Youtube.convertQualityName(player.options().quality),this.player_=player,this.playerEl_=document.getElementById(player.id()),this.playerEl_.className+=" vjs-youtube",this.qualityButton=document.createElement("div"),this.qualityButton.setAttribute("class","vjs-quality-button vjs-menu-button vjs-control"),this.qualityButton.setAttribute("tabindex",0);var qualityContent=document.createElement("div");this.qualityButton.appendChild(qualityContent),this.qualityTitle=document.createElement("span"),qualityContent.appendChild(this.qualityTitle),"undefined"!==player.options().quality&&setInnerText(this.qualityTitle,player.options().quality||"auto");var qualityMenu=document.createElement("div");if(qualityMenu.setAttribute("class","vjs-menu"),this.qualityButton.appendChild(qualityMenu),this.qualityMenuContent=document.createElement("ul"),this.qualityMenuContent.setAttribute("class","vjs-menu-content"),qualityMenu.appendChild(this.qualityMenuContent),this.id_=this.player_.id()+"_youtube_api",this.el_=videojs.Component.prototype.createEl("iframe",{id:this.id_,className:"vjs-tech",scrolling:"no",marginWidth:0,marginHeight:0,frameBorder:0}),this.el_.setAttribute("allowFullScreen",""),this.playerEl_.insertBefore(this.el_,this.playerEl_.firstChild),/MSIE (\d+\.\d+);/.test(navigator.userAgent)){var ieVersion=Number(RegExp.$1);this.addIframeBlocker(ieVersion)}else/(iPad|iPhone|iPod|android)/g.test(navigator.userAgent)||(this.el_.className+=" onDesktop",this.addIframeBlocker());this.parseSrc(player.options().src),this.playOnReady=this.player_.options().autoplay||!1,this.forceSSL=!("undefined"!=typeof this.player_.options().forceSSL&&this.player_.options().forceSSL!==!0),this.forceHTML5=!("undefined"!=typeof this.player_.options().forceHTML5&&this.player_.options().forceHTML5!==!0),this.updateIframeSrc();var self=this;player.ready(function(){var controlBar=self.playerEl_.querySelectorAll(".vjs-control-bar")[0];controlBar.appendChild(self.qualityButton),self.playOnReady&&!self.player_.options().ytcontrols&&("undefined"!=typeof self.player_.loadingSpinner&&self.player_.loadingSpinner.show(),"undefined"!=typeof self.player_.bigPlayButton&&self.player_.bigPlayButton.hide()),player.trigger("loadstart")}),this.on("dispose",function(){this.ytplayer&&this.ytplayer.destroy(),this.player_.options().ytcontrols||this.player_.off("waiting",this.bindedWaiting),this.playerEl_.querySelectorAll(".vjs-poster")[0].style.backgroundImage="none",this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),this.qualityButton.parentNode&&this.qualityButton.parentNode.removeChild(this.qualityButton),"undefined"!=typeof this.player_.loadingSpinner&&this.player_.loadingSpinner.hide(),"undefined"!=typeof this.player_.bigPlayButton&&this.player_.bigPlayButton.hide(),this.iframeblocker&&this.playerEl_.removeChild(this.iframeblocker)})}}),videojs.Youtube.prototype.updateIframeSrc=function(){var params={enablejsapi:1,iv_load_policy:3,playerapiid:this.id(),disablekb:1,wmode:"transparent",controls:this.player_.options().ytcontrols?1:0,html5:this.player_.options().forceHTML5?1:null,playsinline:this.player_.options().playsInline?1:0,showinfo:0,modestbranding:1,rel:0,autoplay:this.playOnReady?1:0,loop:this.player_.options().loop?1:0,list:this.playlistId,vq:this.userQuality,origin:window.location.protocol+"//"+window.location.host};"file:"===window.location.protocol&&delete params.origin;for(var prop in params)!params.hasOwnProperty(prop)||"undefined"!=typeof params[prop]&&null!==params[prop]||delete params[prop];var self=this;if(null===this.videoId)this.el_.src="about:blank",setTimeout(function(){self.triggerReady()},500);else if(this.el_.src=(this.forceSSL||"file:"===window.location.protocol?"https:":window.location.protocol)+"//www.youtube.com/embed/"+this.videoId+"?"+videojs.Youtube.makeQueryString(params),this.player_.options().ytcontrols?this.player_.controls(!1):"undefined"==typeof this.player_.poster()&&setTimeout(function(){var posterEl=self.playerEl_.querySelectorAll(".vjs-poster")[0];posterEl.style.backgroundImage="url(https://img.youtube.com/vi/"+self.videoId+"/0.jpg)",posterEl.style.display=""},100),this.bindedWaiting=function(){self.onWaiting()},this.player_.on("waiting",this.bindedWaiting),videojs.Youtube.apiReady)this.loadYoutube();else if(videojs.Youtube.loadingQueue.push(this),!videojs.Youtube.apiLoading){var tag=document.createElement("script");tag.onerror=function(e){self.onError(e)},tag.src=this.forceSSL||"file:"===window.location.protocol?"https://www.youtube.com/iframe_api":"//www.youtube.com/iframe_api";var firstScriptTag=document.getElementsByTagName("script")[0];firstScriptTag.parentNode.insertBefore(tag,firstScriptTag),videojs.Youtube.apiLoading=!0}},videojs.Youtube.prototype.onWaiting=function(){this.player_.bigPlayButton.hide()},videojs.Youtube.prototype.addIframeBlocker=function(ieVersion){this.iframeblocker=videojs.Component.prototype.createEl("div"),this.iframeblocker.className="iframeblocker",this.iframeblocker.style.position="absolute",this.iframeblocker.style.left=0,this.iframeblocker.style.right=0,this.iframeblocker.style.top=0,this.iframeblocker.style.bottom=0,this.iframeblocker.style.zIndex=9999,ieVersion&&9>ieVersion?this.iframeblocker.style.opacity=.01:this.iframeblocker.style.background="rgba(255, 255, 255, 0.01)";var self=this;addEventListener(this.iframeblocker,"mousemove",function(e){self.player_.userActive()||self.player_.userActive(!0),e.stopPropagation(),e.preventDefault()}),addEventListener(this.iframeblocker,"click",function(){self.paused()?self.play():self.pause()}),this.playerEl_.insertBefore(this.iframeblocker,this.el_.nextSibling)},videojs.Youtube.prototype.parseSrc=function(src){if(this.srcVal=src,src){var regId=/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/,match=src.match(regId);this.videoId=match&&11===match[2].length?match[2]:null;var regPlaylist=/[?&]list=([^#\&\?]+)/;match=src.match(regPlaylist),null!==match&&match.length>1?this.playlistId=match[1]:this.playlistId&&delete this.playlistId;var regVideoQuality=/[?&]vq=([^#\&\?]+)/;match=src.match(regVideoQuality),null!==match&&match.length>1&&(this.userQuality=match[1],setInnerText(this.qualityTitle,videojs.Youtube.parseQualityName(this.userQuality)))}},videojs.Youtube.prototype.src=function(src){if("undefined"!=typeof src){if(this.parseSrc(src),"about:blank"===this.el_.src)return void this.updateIframeSrc();delete this.defaultQuality,null!==this.videoId&&(this.player_.options().autoplay&&this.playVideoIsAllowed?this.ytplayer.loadVideoById({videoId:this.videoId,suggestedQuality:this.userQuality}):this.ytplayer.cueVideoById({videoId:this.videoId,suggestedQuality:this.userQuality}),this.playerEl_.querySelectorAll(".vjs-poster")[0].style.backgroundImage="url(https://img.youtube.com/vi/"+this.videoId+"/0.jpg)",this.player_.poster("https://img.youtube.com/vi/"+this.videoId+"/0.jpg"))}return this.srcVal},videojs.Youtube.prototype.load=function(){},videojs.Youtube.prototype.play=function(){null!==this.videoId&&(this.player_.options().ytcontrols||this.player_.trigger("waiting"),this.isReady_?(this.ytplayer.setVolume(100*this.player_.volume()),this.volumeVal>0?this.ytplayer.unMute():this.ytplayer.mute(),this.playVideoIsAllowed&&this.ytplayer.playVideo()):this.playOnReady=!0)},videojs.Youtube.prototype.pause=function(){this.ytplayer.pauseVideo()},videojs.Youtube.prototype.paused=function(){return this.ytplayer?this.lastState!==YT.PlayerState.PLAYING&&this.lastState!==YT.PlayerState.BUFFERING:!0},videojs.Youtube.prototype.currentTime=function(){return this.ytplayer&&this.ytplayer.getCurrentTime?this.ytplayer.getCurrentTime():0},videojs.Youtube.prototype.setCurrentTime=function(seconds){this.ytplayer.seekTo(seconds,!0),this.player_.trigger("timeupdate")},videojs.Youtube.prototype.duration=function(){return this.ytplayer&&this.ytplayer.getDuration?this.ytplayer.getDuration():0},videojs.Youtube.prototype.currentSrc=function(){return this.srcVal},videojs.Youtube.prototype.volume=function(){return this.ytplayer&&isNaN(this.volumeVal)&&(this.volumeVal=this.ytplayer.getVolume()/100,this.player_.volume(this.volumeVal)),this.volumeVal},videojs.Youtube.prototype.setVolume=function(percentAsDecimal){"undefined"!=typeof percentAsDecimal&&percentAsDecimal!==this.volumeVal&&(this.ytplayer.setVolume(100*percentAsDecimal),this.volumeVal=percentAsDecimal,this.player_.trigger("volumechange"))},videojs.Youtube.prototype.muted=function(){return this.mutedVal},videojs.Youtube.prototype.setMuted=function(muted){muted?(this.ytplayer.mute(),this.player_.volume(0)):(this.ytplayer.unMute(),this.player_.volume(this.volumeVal)),this.mutedVal=muted,this.player_.trigger("volumechange")},videojs.Youtube.prototype.buffered=function(){if(this.ytplayer&&this.ytplayer.getVideoBytesLoaded){var loadedBytes=this.ytplayer.getVideoBytesLoaded(),totalBytes=this.ytplayer.getVideoBytesTotal();if(!loadedBytes||!totalBytes)return 0;var duration=this.ytplayer.getDuration(),secondsBuffered=loadedBytes/totalBytes*duration,secondsOffset=this.ytplayer.getVideoStartBytes()/totalBytes*duration;return videojs.createTimeRange(secondsOffset,secondsOffset+secondsBuffered)}return videojs.createTimeRange(0,0)},videojs.Youtube.prototype.supportsFullScreen=function(){return!0},videojs.Youtube.isSupported=function(){return!0},videojs.Youtube.canPlaySource=function(srcObj){return"video/youtube"===srcObj.type},videojs.Youtube.canControlVolume=function(){return!0},videojs.Youtube.loadingQueue=[],videojs.Youtube.prototype.loadYoutube=function(){this.ytplayer=new YT.Player(this.id_,{events:{onReady:function(e){e.target.vjsTech.onReady()},onStateChange:function(e){e.target.vjsTech.onStateChange(e.data)},onPlaybackQualityChange:function(e){e.target.vjsTech.onPlaybackQualityChange(e.data)},onError:function(e){e.target.vjsTech.onError(e.data)}}}),this.ytplayer.vjsTech=this},videojs.Youtube.makeQueryString=function(args){var array=[];for(var key in args)args.hasOwnProperty(key)&&array.push(key+"="+args[key]);return array.join("&")},window.onYouTubeIframeAPIReady=function(){for(var yt;yt=videojs.Youtube.loadingQueue.shift();)yt.loadYoutube();videojs.Youtube.loadingQueue=[],videojs.Youtube.apiReady=!0},videojs.Youtube.prototype.onReady=function(){this.isReady_=!0,this.triggerReady(),this.player_.trigger("loadedmetadata"),this.player_.trigger("durationchange"),this.player_.trigger("timeupdate"),"undefined"!=typeof this.player_.loadingSpinner&&this.player_.loadingSpinner.hide(),this.player_.options().muted&&this.setMuted(!0),this.playOnReady&&(this.playOnReady=!1,this.play())},videojs.Youtube.prototype.updateQualities=function(){function setupEventListener(el){addEventListener(el,"click",function(){var quality=this.getAttribute("data-val");self.ytplayer.setPlaybackQuality(quality),self.userQuality=quality,setInnerText(self.qualityTitle,videojs.Youtube.parseQualityName(quality));var selected=self.qualityMenuContent.querySelector(".vjs-selected");selected&&videojs.Youtube.removeClass(selected,"vjs-selected"),videojs.Youtube.addClass(this,"vjs-selected")})}var qualities=this.ytplayer.getAvailableQualityLevels(),self=this;if(qualities.indexOf(this.userQuality)<0&&setInnerText(self.qualityTitle,videojs.Youtube.parseQualityName(this.defaultQuality)),0===qualities.length)this.qualityButton.style.display="none";else{for(this.qualityButton.style.display="";this.qualityMenuContent.hasChildNodes();)this.qualityMenuContent.removeChild(this.qualityMenuContent.lastChild);for(var i=0;i=0;i--)classNames[i]===classToRemove&&classNames.splice(i,1);element.className=classNames.join(" ")}};var style=document.createElement("style"),def=" .vjs-youtube .vjs-poster { background-size: 100%!important; }.vjs-youtube .vjs-poster, .vjs-youtube .vjs-loading-spinner, .vjs-youtube .vjs-text-track-display{ pointer-events: none !important; }.vjs-youtube.vjs-user-active .iframeblocker { display: none; }.vjs-youtube.vjs-user-inactive .vjs-tech.onDesktop { pointer-events: none; }.vjs-quality-button > div:first-child > span:first-child { position:relative;top:7px }";style.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(style),style.styleSheet?style.styleSheet.cssText=def:style.appendChild(document.createTextNode(def)),Array.prototype.indexOf||(Array.prototype.indexOf=function(elt){var len=this.length>>>0,from=Number(arguments[1])||0;for(from=0>from?Math.ceil(from):Math.floor(from),0>from&&(from+=len);len>from;from++)if(from in this&&this[from]===elt)return from;return-1})}(); \ No newline at end of file diff --git a/plugins/video/public/style.css b/plugins/video/public/style.css new file mode 100644 index 0000000..0948d53 --- /dev/null +++ b/plugins/video/public/style.css @@ -0,0 +1,25 @@ +.video-gallery-thumbnail { + position: relative; + display: inline-block; + width: 95px; + height: 85px; + margin: 1em; + border: solid #F0F0F0 1px; + vertical-align: top; + text-align: center; + overflow: hidden; + padding-top: 7px; + margin-botton: 10px; +} + +.video-gallery-top-box{ + height: 73px; +} + +.video-duration{ + position: absolute; + bottom: 0px; + background-color: black; + font-size: 1em; + text-color: white; +} diff --git a/plugins/video/views/cms/_video.html.erb b/plugins/video/views/cms/_video.html.erb new file mode 100644 index 0000000..c7fe2f6 --- /dev/null +++ b/plugins/video/views/cms/_video.html.erb @@ -0,0 +1,12 @@ +<%= required_fields_message %> + +
+<%= required f.text_field('name', :size => '64', :maxlength => 150) %> +<%= required labelled_form_field _('URL of the video'), text_field(:article, :video_url, :size => 300) %> +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> +<%= render :partial => 'general_fields' %> +<%= render :partial => 'translatable' %> +
+ + + diff --git a/plugins/video/views/cms/_video_gallery.html.erb b/plugins/video/views/cms/_video_gallery.html.erb new file mode 100644 index 0000000..ce95bd1 --- /dev/null +++ b/plugins/video/views/cms/_video_gallery.html.erb @@ -0,0 +1,6 @@ +<%= required_fields_message %> + +<%= required f.text_field('name', :size => '64', :maxlength => 150) %> +<%= render :partial => 'general_fields' %> + +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> diff --git a/plugins/video/views/cms/video.html.erb b/plugins/video/views/cms/video.html.erb new file mode 100644 index 0000000..7b3ccbb --- /dev/null +++ b/plugins/video/views/cms/video.html.erb @@ -0,0 +1,8 @@ + + + +sdsd \ No newline at end of file diff --git a/plugins/video/views/content_viewer/video.html.erb b/plugins/video/views/content_viewer/video.html.erb new file mode 100644 index 0000000..6bbda38 --- /dev/null +++ b/plugins/video/views/content_viewer/video.html.erb @@ -0,0 +1,34 @@ +
+<%if @page.video_provider=='youtube' %> + + + + + <% elsif @page.video_provider=='vimeo' %> + + + + +<% elsif @page.video_provider=='file' %> + + + +<% end %> +
+
+<% _("Description:") %> +<%= @page.body %> \ No newline at end of file diff --git a/plugins/video/views/content_viewer/video_gallery.html.erb b/plugins/video/views/content_viewer/video_gallery.html.erb new file mode 100644 index 0000000..5cdf88f --- /dev/null +++ b/plugins/video/views/content_viewer/video_gallery.html.erb @@ -0,0 +1,28 @@ +<% +def self.list_videos(configure={}) + configure[:recursive] ||= false + configure[:list_type] ||= :folder + if !configure[:contents].blank? + configure[:contents] = configure[:contents].paginate( + :order => "updated_at DESC", + :per_page => 16, + :page => params[:npage] + ) + render :file => 'shared/video_list', :locals => configure + else + content_tag('em', _('(empty folder)')) + end + end +%> +<% unless video_gallery.body.blank? %> +
+ <%= video_gallery.body %> +
+
+<% end %> + +<% if video_gallery.children.empty? %> + <%= _('(empty video gallery)') %> +<% else %> + <%= list_videos(:contents=>video_gallery.children) %> +<% end %> \ No newline at end of file diff --git a/plugins/video/views/shared/video_list.html.erb b/plugins/video/views/shared/video_list.html.erb new file mode 100644 index 0000000..7233d63 --- /dev/null +++ b/plugins/video/views/shared/video_list.html.erb @@ -0,0 +1,21 @@ +
+ <% contents.each do |content| %> + <%#= py content %> + <% if content.display_to?(user) %> + + <% end %> + <% end %> +

<%= pagination_links contents, :param_name => 'npage', :page_links => true %>

+
\ No newline at end of file -- libgit2 0.21.2