feature/share-libs
rb 153 lines 5.28 KB
Raw
1 require 'google/apis/youtube_v3'
2 require 'google/api_client/client_secrets'
3
4 # Fix this later
5 # rubocop:disable Metrics/ClassLength
6 class YoutubeClient
7 BASE_URI = 'https://youtube.googleapis.com/youtube/v3'.freeze
8
9 def initialize(authorization)
10 raise 'Authorization is required' if authorization.nil?
11
12 @authorization = authorization
13 @token = authorization.token
14 @youtube_export_playlist_count = 0
15 @youtube_export_playlist_items_count = 0
16 end
17
18 def youtube_export_playlist_max_iteration
19 # If development, set to 2, else 10.
20 Rails.env.development? ? 2 : 10
21 end
22
23 # Personal content
24 def search_personal(_keywords)
25 results = service.list_searches('snippet', for_mine: false, q: 'dewa', type: 'video',
26 options: { authorization: auth_client })
27 p results
28 end
29
30 def search(keywords)
31 uri = 'https://www.googleapis.com/youtube/v3/search'
32 client = HTTPClient.new
33 query = { 'key' => 'AIzaSyDhs0-L3B6X_oq0cVn7GIPgvmb5--VlecE', 'q' => keywords, 'type' => 'video',
34 'part' => 'snippet' }
35 header = [
36 ['Accept', 'application/json'],
37 ['Content-Type', 'application/json']
38 ]
39 client.get(uri, query, header)
40 end
41
42 def user_likes_videos(next_page_token = nil)
43 query = { 'key' => ENV['GOOGLE_API_KEY'], 'myRating' => 'like', 'part' => 'snippet,contentDetails,statistics',
44 'maxResults' => '50', 'pageToken' => next_page_token }
45 header = [
46 ['Accept', 'application/json'],
47 ['Authorization', "Bearer #{@token}"]
48 ]
49 client.get("#{BASE_URI}/videos", query, header)
50 end
51
52 # Get user's playlists list
53 def export_user_playlist(next_page_token = nil)
54 @youtube_export_playlist_count += 1
55 response = get_user_playlist(next_page_token)
56 response_json = JSON.parse(response.body)
57 # Return if no playlist found
58 return if response_json['items'].nil?
59
60 # Loop through all playlists items
61 response_json['items'].each do |playlists|
62 # Get playlist items
63 export_user_playlist_items(playlists['id'])
64 end
65
66 # Check playlist pagination
67 if response_json['nextPageToken'].present? && @youtube_export_playlist_count < youtube_export_playlist_max_iteration
68 export_user_playlist(response_json['nextPageToken'])
69 end
70 end
71
72 private
73
74 def client
75 HTTPClient.new
76 end
77
78 def service
79 @service ||= Google::Apis::YoutubeV3::YouTubeService.new
80 end
81
82 def auth_client
83 @auth_client ||= Signet::OAuth2::Client.new(access_token: @token)
84 end
85
86 def get_user_playlist(next_page_token = nil)
87 query = { 'key' => ENV['GOOGLE_API_KEY'], 'maxResults' => '50', 'mine' => true,
88 'pageToken' => next_page_token }
89 header = [
90 ['Accept', 'application/json'],
91 ['Authorization', "Bearer #{@token}"]
92 ]
93 client.get("#{BASE_URI}/playlists", query, header)
94 end
95
96 def export_user_playlist_items(playlist_id, next_page_token = nil)
97 @youtube_export_playlist_items_count += 1
98 response = get_user_playlist_items(playlist_id, next_page_token)
99 response_json = JSON.parse(response.body)
100
101 # Get video ids from playlist items, separated by comma
102 video_ids = response_json['items'].map { |item| item['contentDetails']['videoId'] }.join(',')
103 p "Exporting playlist items: #{video_ids}"
104 get_videos_from_playlist_video_ids(video_ids)
105
106 # Check playlist items pagination
107 if response_json['nextPageToken'].present? && @youtube_export_playlist_items_count < youtube_export_playlist_max_iteration
108 export_user_playlist_items(playlist_id, response_json['nextPageToken'])
109 end
110 end
111
112 def get_user_playlist_items(id, next_page_token = nil)
113 query = { 'key' => ENV['GOOGLE_API_KEY'], 'part' => 'snippet,contentDetails', 'maxResults' => '50',
114 'playlistId' => id, 'pageToken' => next_page_token }
115 header = [
116 ['Accept', 'application/json'],
117 ['Authorization', "Bearer #{@token}"]
118 ]
119 client.get("#{BASE_URI}/playlistItems", query, header)
120 end
121
122 def get_videos_from_playlist_video_ids(video_ids)
123 response = user_videos({ 'id' => video_ids })
124 response_json = JSON.parse(response.body)
125 p "Exporting videos from playlist: #{response_json}"
126 export_youtube_videos(response_json['items'], @authorization.user_id)
127 end
128
129 def export_youtube_videos(items, user_id)
130 music_videos = items.select { |item| item['snippet']['categoryId'] == '10' }
131 music_videos.each do |video|
132 SongProvider.upsert(
133 { user_id: user_id, provider_type: :youtube, provider_id: video['id'], name: video['snippet']['title'],
134 preview_url: "https://www.youtube.com/watch?v=#{video['id']}", description: video['snippet']['description'],
135 image_url: video['snippet']['thumbnails']['high']['url'] },
136 unique_by: :index_song_providers_on_provider_id_and_provider_type
137 )
138 end
139 end
140
141 def user_videos(additional_query, next_page_token = nil)
142 p "Additional query: #{additional_query}"
143 query = { 'key' => ENV['GOOGLE_API_KEY'], 'part' => 'snippet,contentDetails,statistics',
144 'maxResults' => '50', 'pageToken' => next_page_token }
145 query = query.merge(additional_query)
146 p "Query: #{query}"
147 header = [
148 ['Accept', 'application/json'],
149 ['Authorization', "Bearer #{@token}"]
150 ]
151 client.get("#{BASE_URI}/videos", query, header)
152 end
153 end