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
Source
# File lib/yt/collections/videos.rb, line 11 def where(requirements = {}) @published_before = nil @halt_list = false super end
Yt::Collections::Base#where
Private Instance Methods
Source
# 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
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
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
Source
# 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
Yt::Actions::List#eager_load_items_from
Source
# File lib/yt/collections/videos.rb, line 124 def halt_list @halt_list = true end
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
Source
# 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
@return [Hash] the parameters to submit to YouTube to list videos. @see developers.google.com/youtube/v3/docs/search/list
Yt::Actions::List#list_params
Source
# File lib/yt/collections/videos.rb, line 128 def more_pages? (@last_index.zero? && !@halt_list) || !@page_token.nil? end
Source
# 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
Yt::Actions::List#next_page
Source
# File lib/yt/collections/videos.rb, line 156 def use_list_endpoint? @where_params ||= {} @parent.nil? && (@where_params.keys & [:id, :chart]).any? end
@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.
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
Source
# File lib/yt/collections/videos.rb, line 145 def videos_path use_list_endpoint? ? '/youtube/v3/videos' : '/youtube/v3/search' end