class ActivePublicResources::Drivers::Youtube

Constants

API_KEY
DRIVER_NAME

Public Class Methods

new(config_options={}) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 11
def initialize(config_options={})
  @default_request_criteria = {}
  if config_options[:default_request_criteria]
    @default_request_criteria = config_options[:default_request_criteria]
  end
end

Public Instance Methods

perform_request(request_criteria) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 18
def perform_request(request_criteria)
  request_criteria.set_default_criteria!(@default_request_criteria)
  unless request_criteria.validate_presence(:query) || request_criteria.validate_presence(:channel)
    raise ArgumentError, "You must specify at least a query or channel"
  end

  uri = URI('https://www.googleapis.com/youtube/v3/search')
  params = {
    q: request_criteria.query,
    part: 'snippet',
    type: 'video',
    order: sort(request_criteria.sort),
    safeSearch: content_filter(request_criteria.content_filter),
    maxResults: request_criteria.per_page || 25,
    key: API_KEY
  }

  params['pageToken'] = request_criteria.page if request_criteria.page && request_criteria.page != 1
  params['userIp'] = request_criteria.remote_ip if request_criteria.remote_ip
  params['channelId'] = channel_id(request_criteria.channel_name) if channel_id(request_criteria.channel_name)

  uri.query = URI.encode_www_form(params)
  res = Net::HTTP.get_response(uri)
  results = JSON.parse(res.body)
  return video_details(request_criteria, results)
end

Private Instance Methods

channel_id(channel_name) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 47
def channel_id(channel_name)
  # we are getting the name of the channel.
  # we need to figure out its ID
  if channel_name
    uri = URI('https://www.googleapis.com/youtube/v3/search')
    params = {
      q: channel_name,
      part: 'id',
      type: 'channel',
      key: API_KEY
    }
    uri.query = URI.encode_www_form(params)
    res = Net::HTTP.get_response(uri)
    results = JSON.parse(res.body)
    return results['items'].first['id']['channelId'] unless results['items'].empty?
  end

  return false
end
content_filter(val) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 90
def content_filter(val)
  case val
    when APR::RequestCriteria::CONTENT_FILTER_NONE
      'strict'
    when APR::RequestCriteria::CONTENT_FILTER_STRICT
      'strict'
    else
      'strict'
  end
end
next_criteria(request_criteria, results) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 110
def next_criteria(request_criteria, results)
  if results['nextPageToken']
    return RequestCriteria.new({
      channel_name: request_criteria.channel_name,
      query: request_criteria.query,
      page: results['nextPageToken'],
      per_page: results['pageInfo']['resultsPerPage'].to_i
    })
  end
end
parse_results(request_criteria, results, videos) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 101
def parse_results(request_criteria, results, videos)
  @driver_response = DriverResponse.new(
    criteria: request_criteria,
    next_criteria: next_criteria(request_criteria, results),
    total_items: results['pageInfo']['totalResults'].to_i,
    items: videos.map { |video| parse_video(video) }
  )
end
parse_video(item) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 121
def parse_video(item)
  video_id = item['id']
  snippet = item['snippet']
  statistics = item['statistics'] ? item['statistics'] : {}
  details = item['contentDetails']
  video = APR::ResponseTypes::Video.new
  video.id             = video_id
  video.title          = snippet['title']
  video.description    = snippet['description']
  video.thumbnail_url  = snippet['thumbnails']['default']['url']
  video.url            = "https://www.youtube-nocookie.com/embed/#{video_id}?feature=oembed&rel=0"
  video.duration       = ISO8601::Duration.new(details['duration']).to_seconds
  video.num_views      = statistics['viewCount'] ? statistics['viewCount'].to_i : 0
  video.num_likes      = statistics['likeCount'] ? statistics['likeCount'].to_i : 0
  video.num_comments   = statistics['commentCount'] ? statistics['commentCount'].to_i : 0
  video.created_date   = Date.parse(snippet['publishedAt'])
  video.username       = snippet['channelTitle']
  video.width          = 640
  video.height         = 360

  # Return Types

  video.return_types << APR::ReturnTypes::Url.new(
    driver: DRIVER_NAME,
    remote_id: video.id,
    url: video.url,
    text: video.title,
    title: video.title
  )

  video.return_types << APR::ReturnTypes::Iframe.new(
    driver: DRIVER_NAME,
    remote_id: video.id,
    url: video.url,
    text: video.title,
    title: video.title,
    width: 640,
    height: 360
  )

  video
end
sort(val) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 77
def sort(val)
  case val
    when APR::RequestCriteria::SORT_RELEVANCE
      'relevance'
    when APR::RequestCriteria::SORT_RECENT
      'date'
    when APR::RequestCriteria::SORT_POPULAR
      'viewCount'
    else
      'relevance'
  end
end
video_details(request_criteria, results) click to toggle source
# File lib/active_public_resources/drivers/youtube.rb, line 67
def video_details(request_criteria, results)
  video_ids = results['items'].map { |item| item['id']['videoId']}
  uri = URI('https://www.googleapis.com/youtube/v3/videos')
  params = { 'part' => 'snippet,contentDetails,statistics', 'id' => video_ids.join(','), 'key' => API_KEY }
  uri.query = URI.encode_www_form(params)
  res = Net::HTTP.get_response(uri)
  videos = JSON.parse(res.body)['items']
  return parse_results(request_criteria, results, videos)
end