app/models/presentation.rb
class Presentation < ActiveRecord::Base
has_friendly_id :title, :use_slug => true
validates :title, :description, :presented_at, :presenter_names, :presence => true
validates :slides_url, :video_url, :meetup_url, :format => { :with => /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/i, :allow_blank => true, :message => 'invalid URL' }
has_many :presentation_presenters
has_many :presenters, :through => :presentation_presenters
before_validation :set_description
def self.find_all_by_cached_slug_or_id(id)
where(arel_table[:cached_slug].eq(id).or(arel_table[:id].eq(id)))
end
def self.group_by_date(order = :desc)
order("presented_at #{order}").group_by(&:presented_at)
end
def self.past_or_by_month(params = {})
relation = order('presented_at desc')
if params[:month]
month = Date.parse(params[:month])
relation = relation.where(arel_table[:presented_at].gteq(month.beginning_of_month))
relation = relation.where(arel_table[:presented_at].lteq(month.end_of_month))
else
relation = relation.where(arel_table[:presented_at].lt(DateTime.current.to_date))
end
relation.page(params[:page]).per(params[:per])
end
def self.all_or_by_month(params = {})
relation = order('presented_at desc')
if params[:month]
month = Date.parse(params[:month])
relation = relation.where(arel_table[:presented_at].gteq(month.beginning_of_month))
relation = relation.where(arel_table[:presented_at].lteq(month.end_of_month))
end
relation.page(params[:page]).per(params[:per] || 10)
end
def self.upcoming
where(arel_table[:presented_at].gteq(DateTime.current.to_date).and(arel_table[:presented_at].lteq(1.month.from_now)))
end
def self.next_upcoming_month
upcoming.order('presented_at asc').limit(1).first.try { |presentation| presentation.presented_at.strftime('%B-%Y') }
end
def self.video_providers
VideoProviders
end
def set_description
if read_attribute(:description).blank?
write_attribute(:description, 'Description pending...')
end
end
def presenter=(presenter)
self.presenters << presenter
end
def presenter_names=(names)
# When editing the presentation, we may remove presenters. To make sure the record
# removes presenters correctly, we remove the old presenters before assigning the current ones
self.presenters.clear
(names || '').split(/,|&/ix).each { |presenter_name| self.presenter_name = presenter_name.strip }
end
def presenter_names
presenters.map(&:name).join(', ')
end
def presenter_name=(name)
new_presenter = Presenter.find_or_initialize_by_name(name)
self.presenters << new_presenter
new_presenter.name
end
VideoProviders = %w{youtube vimeo blip}
VideoDimensions = { :width => 625, :height => 370 }
def video_url=(url)
if url.present?
self.video_provider = get_video_provider(url)
self.video_id = get_video_id(url)
self.video_offset = get_video_offset(url)
end
end
def video_url
unless video_provider.blank? || video_id.blank?
self.send("#{video_provider}_url")
end
end
def embed_video
self.send("embed_#{video_provider}")
end
private
def get_video_provider(url)
VideoProviders.detect { |provider| url.match(provider) }
end
def get_video_attributes(url)
Array.wrap(self.send("#{self.video_provider}_match", url))
end
def get_video_id(url)
get_video_attributes(url)[0]
end
def get_video_offset(url)
get_video_attributes(url)[1]
end
# Vimeo methods
def vimeo_match(url)
url.match(/https?:\/\/(\w+\.)?vimeo.com\/(.+)/)[2]
end
def vimeo_url
%{http://vimeo.com/#{video_id}}
end
def embed_vimeo
%{<iframe src="http://player.vimeo.com/video/#{video_id}" width="#{VideoDimensions[:width]}" height="#{VideoDimensions[:height]}" frameborder="0"></iframe>}
end
# Youtube methods
def youtube_match(url)
url.match(/http:\/\/www\.youtube\.com\/watch\/?\?v=([^&]+)&?t?=?([^&]+)?/)[1..2]
end
def youtube_url
%{http://www.youtube.com/watch?v=#{video_id}}
end
def embed_youtube
%{<iframe width="#{VideoDimensions[:width]}" height="#{VideoDimensions[:height]}" src="http://www.youtube.com/embed/#{video_id}?start=#{youtube_start_time}" frameborder="0" allowfullscreen></iframe>}
end
def youtube_start_time
if video_offset.present?
parsed_offset = video_offset.match(/(\d+)m(\d+)s/)
parsed_offset[1].to_i * 60 + parsed_offset[2].to_i
else
0
end
end
# Blip.tv methods
def blip_match(url)
url.match(/http:\/\/blip\.tv\/play\/(.+)/)[1]
end
def blip_url
%{http://blip.tv/play/#{video_id}}
end
def embed_blip
%{<embed src="http://blip.tv/play/#{video_id}" type="application/x-shockwave-flash" width="#{VideoDimensions[:width]}" height="#{VideoDimensions[:height]}" allowscriptaccess="always" allowfullscreen="true"></embed>}
end
end