class Yt::Collections::Videos

Provides methods to interact with a collection of YouTube videos.

Resources with videos are: {Yt::Models::Channel channels} and {Yt::Models::Account accounts}.

Public Instance Methods

where(requirements = {}) click to toggle source
Calls superclass method Yt::Collections::Base#where
# File lib/yt/collections/videos.rb, line 11
def where(requirements = {})
  @published_before = nil
  @halt_list = false
  super
end

Private Instance Methods

add_offset_to(items) click to toggle source

According to stackoverflow.com/a/23256768 YouTube does not provide more than 500 results for any query. In order to overcome that limit, the query is restarted with a publishedBefore filter in case there are more videos to be listed for a channel

# File lib/yt/collections/videos.rb, line 107
def add_offset_to(items)
  @fetched_items ||= 0
  if (@fetched_items += items.count) >= 500
    last_published = items.last['snippet']['publishedAt']
    last_published = DateTime.rfc3339(last_published) - 1.second
    last_published = last_published.strftime '%FT%T.999Z'
    @page_token, @published_before, @fetched_items = '', last_published, 0
  elsif (1...50) === @last_index % 50
    @halt_list, @page_token = true, nil
    @last_index += items.size
  end
end
attributes_for_new_item(data) click to toggle source
# File lib/yt/collections/videos.rb, line 19
def attributes_for_new_item(data)
  id = use_list_endpoint? ? data['id'] : data['id']['videoId']
  snippet = data['snippet'].reverse_merge complete: false if data['snippet']
  {}.tap do |attributes|
    attributes[:id] = id
    attributes[:snippet] = snippet
    attributes[:status] = data['status']
    attributes[:content_details] = data['contentDetails']
    attributes[:statistics] = data['statistics']
    attributes[:video_category] = data['videoCategory']
    attributes[:claim] = data['claim']
    attributes[:auth] = @auth
  end
end
eager_load_items_from(items) click to toggle source
Calls superclass method Yt::Actions::List#eager_load_items_from
# File lib/yt/collections/videos.rb, line 34
def eager_load_items_from(items)
  if included_relationships.any?
    associations = [:claim, :category]
    if (included_relationships & associations).any?
      included_relationships.append(:snippet).uniq!
    end

    ids = items.map{|item| item['id']['videoId']}
    parts = (included_relationships - associations).map do |r|
      r.to_s.camelize(:lower)
    end
    conditions = { id: ids.join(','), part: parts.join(',') }
    videos = Collections::Videos.new(auth: @auth).where conditions

    items.each do |item|
      video = videos.find{|v| v.id == item['id']['videoId']}
      parts.each do |part|
        item[part] = case part
          when 'snippet' then video.snippet.data.merge complete: true
          when 'status' then video.status.data
          when 'statistics' then video.statistics_set.data
          when 'contentDetails' then video.content_detail.data
        end
      end if video
    end

    if included_relationships.include? :claim
      video_ids = items.map{|item| item['id']['videoId']}.uniq
      conditions = {
        video_id: video_ids.join(','),
        include_third_party_claims: false
      }
      claims = @parent.claims.includes(:asset).where conditions
      items.each do |item|
        claim = claims.find { |c| c.video_id == item['id']['videoId']}
        item['claim'] = claim
      end
    end

    if included_relationships.include? :category
      category_ids = items.map{|item| item['snippet']['categoryId']}.uniq
      conditions = {id: category_ids.join(',')}
      video_categories = Collections::VideoCategories.new(auth: @auth).where conditions

      items.each do |item|
        video_category = video_categories.find{|v| v.id == item['snippet']['categoryId']}
        item['videoCategory'] = video_category.data
      end
    end
  end
  super
end
halt_list() click to toggle source

If we ask for a list of videos matching specific IDs and no video is returned (e.g. they are all private/deleted), then we don’t want to switch from /videos to /search and keep on looking for videos, but simply return an empty array of items

# File lib/yt/collections/videos.rb, line 124
def halt_list
  @halt_list = true
end
list_params() click to toggle source

@return [Hash] the parameters to submit to YouTube to list videos. @see developers.google.com/youtube/v3/docs/search/list

Calls superclass method Yt::Actions::List#list_params
# File lib/yt/collections/videos.rb, line 89
def list_params
  super.tap do |params|
    params[:params] = videos_params
    params[:path] = videos_path
  end
end
more_pages?() click to toggle source
# File lib/yt/collections/videos.rb, line 128
def more_pages?
  (@last_index.zero? && !@halt_list) || !@page_token.nil?
end
next_page() click to toggle source
Calls superclass method Yt::Actions::List#next_page
# File lib/yt/collections/videos.rb, line 96
def next_page
  super.tap do |items|
    halt_list if use_list_endpoint? && items.empty? && @page_token.nil?
    add_offset_to(items) if !use_list_endpoint? && videos_params[:order] == 'date' && !(videos_params[:for_mine] || videos_params[:for_content_owner])
  end
end
use_list_endpoint?() click to toggle source

@private YouTube API provides two different endpoints to get a list of videos: /videos should be used when the query specifies video IDs or a chart, /search otherwise. @return [Boolean] whether to use the /videos endpoint. @todo: This is one of three places outside of base.rb where @where_params

is accessed; it should be replaced with a filter on params instead.
# File lib/yt/collections/videos.rb, line 156
def use_list_endpoint?
  @where_params ||= {}
  @parent.nil? && (@where_params.keys & [:id, :chart]).any?
end
videos_params() click to toggle source
# File lib/yt/collections/videos.rb, line 132
def videos_params
  {}.tap do |params|
    params[:type] = :video
    params[:max_results] = 50
    params[:part] = 'snippet'
    params[:order] = 'date'
    params.merge! @parent.videos_params if @parent
    apply_where_params! params
    params[:published_before] = @published_before if @published_before
    params
  end
end
videos_path() click to toggle source
# File lib/yt/collections/videos.rb, line 145
def videos_path
  use_list_endpoint? ? '/youtube/v3/videos' : '/youtube/v3/search'
end