Skip to content

Instantly share code, notes, and snippets.

@walterdavis
Forked from jmarsh24/video.rb
Created March 10, 2021 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save walterdavis/3bfe3b2f54a4ef30f8d52fc958526b16 to your computer and use it in GitHub Desktop.
Save walterdavis/3bfe3b2f54a4ef30f8d52fc958526b16 to your computer and use it in GitHub Desktop.
# == Schema Information
#
# Table name: videos
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# title :text
# youtube_id :string
# leader_id :bigint
# follower_id :bigint
# description :string
# duration :integer
# upload_date :date
# view_count :integer
# tags :string
# song_id :bigint
# youtube_song :string
# youtube_artist :string
# acrid :string
# spotify_album_id :string
# spotify_album_name :string
# spotify_artist_id :string
# spotify_artist_id_2 :string
# spotify_artist_name :string
# spotify_artist_name_2 :string
# spotify_track_id :string
# spotify_track_name :string
# youtube_song_id :string
# isrc :string
# acr_response_code :integer
# channel_id :bigint
# scanned_song :boolean default(FALSE)
# hidden :boolean default(FALSE)
# hd :boolean default(FALSE)
# popularity :integer default(0)
# like_count :integer default(0)
# dislike_count :integer default(0)
# favorite_count :integer default(0)
# comment_count :integer default(0)
# event_id :bigint
# scanned_youtube_music :boolean default(FALSE)
# click_count :integer default(0)
#
class Video < ApplicationRecord
include Filterable
validates :youtube_id, presence: true, uniqueness: true
belongs_to :leader, optional: true, counter_cache: true
belongs_to :follower, optional: true, counter_cache: true
belongs_to :song, optional: true, counter_cache: true
belongs_to :channel, optional: false, counter_cache: true
belongs_to :event, optional: true, counter_cache: true
scope :filter_by_orchestra, ->(song_artist) { joins(:song).where("songs.artist ILIKE ?", song_artist) }
scope :filter_by_genre, ->(song_genre) { joins(:song).where("songs.genre ILIKE ?", song_genre) }
scope :filter_by_leader, ->(leader_name) { joins(:leader).where("leaders.name ILIKE ?", leader_name) }
scope :filter_by_follower, ->(follower_name) { joins(:follower).where("followers.name ILIKE ?", follower_name) }
scope :filter_by_channel, ->(channel_title) { joins(:channel).where("channels.title ILIKE ?", channel_title) }
scope :filter_by_event_id, ->(event_id) { where(event_id: event_id) }
scope :filter_by_song_id, ->(song_id) { where(song_id: song_id) }
scope :filter_by_hd, ->(boolean) { where(hd: boolean) }
scope :filter_by_hidden, -> { where(hidden: true) }
scope :filter_by_not_hidden, -> { where(hidden: false) }
scope :paginate, ->(page, per_page) { offset(per_page * (page - 1)).limit(per_page) }
# Active Admin scopes
scope :has_song, -> { where.not(song_id: nil) }
scope :has_leader, -> { where.not(leader_id: nil) }
scope :has_follower, -> { where.not(follower_id: nil) }
scope :has_youtube_match, -> { where.not(youtube_artist: nil) }
scope :missing_follower, -> { where(follower_id: nil) }
scope :missing_leader, -> { where(leader_id: nil) }
scope :missing_song, -> { where(song_id: nil) }
# Youtube Music Scopes
scope :scanned_youtube_music, -> { where(scanned_youtube_music: true) }
scope :unscanned_youtube_music, -> { where(scanned_youtube_music: false) }
scope :has_youtube_song, -> { where.not(youtube_song: nil) }
# AcrCloud Response scopes
scope :successful_acrcloud, -> { where(acr_response_code: 0) }
scope :unsuccesful_acrcloud, -> { where.not(acr_response_code: [0, 1001]).or(Video.where(acr_response_code: nil)) }
scope :scanned_acrcloud, -> { where(acr_response_code: [0, 1001]) }
scope :unscanned_acrcloud, -> { where.not(acr_response_code: [0, 1001]).or(Video.where(acr_response_code: nil)) }
# Attribute Matching Scopes
scope :with_song_title, lambda { |song_title|
where("unaccent(spotify_track_name) ILIKE unaccent(:song_title)
OR unaccent(youtube_song) ILIKE unaccent(:song_title)
OR unaccent(title) ILIKE unaccent(:song_title)
OR unaccent(description) ILIKE unaccent(:song_title)
OR unaccent(tags) ILIKE unaccent(:song_title)
OR unaccent(acr_cloud_track_name) ILIKE unaccent(:song_title)",
song_title: "%#{song_title}%")
}
scope :with_song_artist_keyword, lambda { |song_artist_keyword|
where("spotify_artist_name ILIKE :song_artist_keyword
OR unaccent(spotify_artist_name_2) ILIKE unaccent(:song_artist_keyword)
OR unaccent(youtube_artist) ILIKE unaccent(:song_artist_keyword)
OR unaccent(description) ILIKE unaccent(:song_artist_keyword)
OR unaccent(title) ILIKE unaccent(:song_artist_keyword)
OR unaccent(tags) ILIKE unaccent(:song_artist_keyword)
OR unaccent(spotify_album_name) ILIKE unaccent(:song_artist_keyword)
OR unaccent(acr_cloud_album_name) ILIKE unaccent(:song_artist_keyword)
OR unaccent(acr_cloud_artist_name) ILIKE unaccent(:song_artist_keyword)
OR unaccent(acr_cloud_artist_name_1) ILIKE unaccent(:song_artist_keyword)",
song_artist_keyword: "%#{song_artist_keyword}%")
}
scope :with_dancer_name_in_title, lambda { |dancer_name|
where("unaccent(title) ILIKE unaccent(:dancer_name)", dancer_name: "%#{dancer_name}%")
}
# Combined Scopes
scope :title_match_missing_leader, ->(leader_name) { missing_leader.with_dancer_name_in_title(leader_name) }
scope :title_match_missing_follower, ->(follower_name) { missing_follower.with_dancer_name_in_title(follower_name) }
class << self
# Filters videos by the results from the materialized
# full text search out of from VideosSearch
def filter_by_query(query)
where(id: VideosSearch.search(query).select(:video_id))
end
end
def any_song_attributes
el_recodo_attributes || spotify_attributes || youtube_attributes || acr_cloud_attributes
end
def external_song_attributes
spotify_attributes || youtube_attributes || acr_cloud_attributes
end
def el_recodo_attributes
return if song.blank?
[song.title, song.artist, song.genre].compact.map(&:titleize).join(" - ")
end
def spotify_attributes
return if spotify_track_name.blank? || spotify_artist_name.blank?
[spotify_track_name, spotify_artist_name].compact.map(&:titleize).join(" - ")
end
def youtube_attributes
return if youtube_song.blank? || youtube_artist.blank?
[youtube_song, youtube_artist].compact.map(&:titleize).join(" - ")
end
def acr_cloud_attributes
return if acr_cloud_track_name.blank? || acr_cloud_artist_name.blank?
[acr_cloud_track_name, acr_cloud_artist_name].compact.map(&:titleize).join(" - ")
end
def dancer_names
return if leader.blank? || follower.blank?
[leader.name, follower.name].compact.map(&:titleize).join(" & ")
end
def formatted_upload_date
return if upload_date.blank?
upload_date.strftime("%B %Y")
end
def clicked!
self.click_count += 1
self.popularity += 1
save!
end
end
<div class="video-info-primary-container">
<div class="show-video-title">
<%= link_to_primary_title(@video.dancer_names, @video.title, @video.any_song_attributes, @video.youtube_id) %>
</div>
<div class="show-video-song">
<%= link_to_song(@video.el_recodo_attributes, @video.external_song_attributes) %>
</div>
<div class="show-video-event">
<%= link_to @video.event.title.titleize, root_path(event_id: @video.event.id), {'data-turbo-frame': "_top"} if @video.event.present? %>
</div>
<div class="show-video-channel">
<%= link_to image_tag(@video.channel.thumbnail_url, class: 'channel-icon'), root_path(channel: @video.channel.title) if @video.channel.thumbnail_url.present? %>
<%= link_to truncate(@video.channel.title, length: 45, omission: ''), root_path(channel: @video.channel.title), class: "channel-title" if @video.channel.title.present? %>
</div>
<div class="show-video-metadata">
<%= formatted_metadata(@video) %>
</div>
</div>
module VideosHelper
def formatted_view_count(view_count)
number_to_human(view_count,
format: "%n%u",
precision: 2,
units: { thousand: "K",
million: "M",
billion: "B" })
end
def formatted_upload_date(upload_date)
upload_date.strftime("%B %Y")
end
def link_to_query(external_song_attributes)
link_to external_song_attributes,
root_path(query: external_song_attributes),
{ 'data-turbo-frame': "_top" }
end
def link_to_song_id(song_attributes)
link_to song_attributes,
root_path(song_id: song_attributes),
{ 'data-turbo-frame': "_top" }
end
def link_to_song(el_recodo_attributes, external_song_attributes)
if el_recodo_attributes.present?
link_to_song_id(el_recodo_attributes)
elsif external_song_attributes.present?
link_to_query(external_song_attributes)
end
end
def link_to_primary_title(dancer_names, title, song_attributes, youtube_id)
if dancer_names.present? && song_attributes.present?
link_to dancer_names,
root_path(v: youtube_id),
{ 'data-turbo-frame': "_top" }
else
link_to truncate(title, length: 85),
root_path(v: youtube_id),
{ 'data-turbo-frame': "_top" }
end
end
def formatted_metadata(video)
[formatted_upload_date(video.upload_date),
video.view_count.to_s + " views",
video.like_count.to_s + " likes"].compact.join(" • ")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment