| 1 | # frozen_string_literal: true |
| 2 | |
| 3 | class SpotifyOnboardingExportJob < ApplicationJob |
| 4 | queue_as :default |
| 5 | |
| 6 | def perform(user_id, time_range) |
| 7 | @user = User.find_by_id(user_id) |
| 8 | @time_range = time_range || 'medium_term' |
| 9 | @client = SpotifyClient.new(@user&.spotify) |
| 10 | |
| 11 | spotify_export_artist |
| 12 | spotify_export_tracks |
| 13 | end |
| 14 | |
| 15 | private |
| 16 | |
| 17 | def spotify_export_artist |
| 18 | res = @client.user_top_items_request('artists', @time_range) |
| 19 | response = JSON.parse(res.body) |
| 20 | items = response['items'] |
| 21 | # p response |
| 22 | items&.each do |item| |
| 23 | # p "spotify_export_artist: #{item}" |
| 24 | artist = ArtistProvider.find_by(provider_id: item['id'], provider_type: provider_type) |
| 25 | add_artist(item) if artist.nil? |
| 26 | end |
| 27 | end |
| 28 | |
| 29 | def add_artist(item) |
| 30 | genres = item['genres'].nil? ? '' : item['genres'].join(',') |
| 31 | |
| 32 | artist = ArtistProvider.new(user_id: @user.id, provider_id: item['id'], |
| 33 | provider_type: provider_type, |
| 34 | name: item['name'], genres: genres) |
| 35 | return unless artist.save |
| 36 | end |
| 37 | |
| 38 | def spotify_export_tracks |
| 39 | res = @client.user_top_items_request('tracks', @time_range) |
| 40 | response = JSON.parse(res.body) |
| 41 | items = response['items'] |
| 42 | |
| 43 | items&.each do |item| |
| 44 | # p "spotify_export_tracks: #{item}" |
| 45 | # Export tracks from the album. |
| 46 | # Do not export track directly. |
| 47 | export_album_if_possible(item['album']) |
| 48 | end |
| 49 | end |
| 50 | |
| 51 | def export_artists_from_tracks(artists) |
| 52 | artists.each do |artist| |
| 53 | artist_provider = ArtistProvider.find_by(provider_id: artist['id'], |
| 54 | provider_type: provider_type) |
| 55 | add_artist(artist) if artist_provider.nil? |
| 56 | end |
| 57 | end |
| 58 | |
| 59 | def export_album_if_possible(album) |
| 60 | album_provider = AlbumProvider.find_by(provider_id: album['id'], |
| 61 | provider_type: provider_type) |
| 62 | if album_provider.nil? |
| 63 | album_provider = AlbumProvider.new(user_id: @user.id, provider_id: album['id'], |
| 64 | provider_type: provider_type, |
| 65 | name: album['name']) |
| 66 | return unless album_provider.save |
| 67 | end |
| 68 | |
| 69 | # ActiveRecord id, Spotify id |
| 70 | export_album_tracks(album_provider.id, album_provider.provider_id) |
| 71 | end |
| 72 | |
| 73 | def export_album_tracks(album_id, album_provider_id) |
| 74 | res = @client.album_tracks_request(album_provider_id) |
| 75 | response = JSON.parse(res.body) |
| 76 | items = response['items'] |
| 77 | |
| 78 | items&.each do |item| |
| 79 | export_song_if_possible(item, album_id) |
| 80 | end |
| 81 | end |
| 82 | |
| 83 | def export_song_if_possible(song, _album_id) |
| 84 | song_provider = SongProvider.find_by(provider_id: song['id'], provider_type: provider_type) |
| 85 | if song_provider.nil? |
| 86 | song_provider = SongProvider.new(user_id: @user.id, provider_id: song['id'], provider_type: provider_type, |
| 87 | name: song['name'], preview_url: song['preview_url']) |
| 88 | song_provider.save |
| 89 | end |
| 90 | end |
| 91 | |
| 92 | def provider_type |
| 93 | ArtistProvider.provider_types[:spotify] |
| 94 | end |
| 95 | end |