| 1 | # frozen_string_literal: true |
| 2 | |
| 3 | class SpotifySyncExportJob < ApplicationJob |
| 4 | def perform(user_id) |
| 5 | @user = User.find_by_id(user_id) |
| 6 | @client = SpotifyClient.new(@user&.spotify) |
| 7 | |
| 8 | spotify_export_recently_played |
| 9 | end |
| 10 | |
| 11 | private |
| 12 | |
| 13 | def spotify_export_recently_played |
| 14 | res = @client.user_recently_played_request |
| 15 | response = JSON.parse(res.body) |
| 16 | # p response |
| 17 | items = response['items'] |
| 18 | |
| 19 | items&.each do |item| |
| 20 | # Export tracks and artists from the album. |
| 21 | # Do not export them directly. |
| 22 | export_album_if_possible(item['track']['album']) |
| 23 | end |
| 24 | end |
| 25 | |
| 26 | def export_album_if_possible(album) |
| 27 | album_provider = AlbumProvider.find_by(provider_id: album['id'], |
| 28 | provider_type: provider_type) |
| 29 | if album_provider.nil? |
| 30 | album_provider = AlbumProvider.new(user_id: @user.id, provider_id: album['id'], |
| 31 | provider_type: provider_type, |
| 32 | name: album['name']) |
| 33 | return unless album_provider.save |
| 34 | end |
| 35 | |
| 36 | # ActiveRecord id, Spotify id |
| 37 | export_album_tracks(album_provider.id, album_provider.provider_id) |
| 38 | end |
| 39 | |
| 40 | def export_album_tracks(album_id, album_provider_id) |
| 41 | res = @client.album_tracks_request(album_provider_id) |
| 42 | response = JSON.parse(res.body) |
| 43 | items = response['items'] |
| 44 | |
| 45 | items&.each do |item| |
| 46 | export_song_if_possible(item) |
| 47 | end |
| 48 | end |
| 49 | |
| 50 | def export_song_if_possible(song) |
| 51 | song_provider = SongProvider.find_by(provider_id: song['id'], provider_type: provider_type) |
| 52 | if song_provider.nil? |
| 53 | song_provider = SongProvider.new(user_id: @user.id, provider_id: song['id'], provider_type: provider_type, |
| 54 | name: song['name'], preview_url: song['preview_url']) |
| 55 | song_provider.save |
| 56 | end |
| 57 | |
| 58 | # Export all artists for this song, and add it to song_artists table |
| 59 | export_song_artists(song_provider.id, song['artists']) |
| 60 | end |
| 61 | |
| 62 | def export_song_artists(song_provider_id, artists) |
| 63 | artists&.each do |artist| |
| 64 | artist_provider = ArtistProvider.find_by(provider_id: artist['id'], provider_type: provider_type) |
| 65 | if artist_provider.nil? |
| 66 | export_song_artist(artist['id'], song_provider_id) |
| 67 | next |
| 68 | end |
| 69 | |
| 70 | add_song_artist_if_needed(song_provider_id, artist_provider.id) |
| 71 | end |
| 72 | end |
| 73 | |
| 74 | def add_song_artist_if_needed(song_provider_id, _artist_provider_id) |
| 75 | song_artist = SongArtist.find_by(song_provider_id: song_provider_id) |
| 76 | return unless song_artist.nil? |
| 77 | |
| 78 | song_artist = SongArtist.new(song_provider_id: song_provider_id) |
| 79 | song_artist.save |
| 80 | end |
| 81 | |
| 82 | def export_song_artist(artist_id, song_provider_id) |
| 83 | response = @client.artist_detail_request(artist_id) |
| 84 | response_json = JSON.parse(response.body) |
| 85 | # p response_json |
| 86 | add_artist_provider(response_json, song_provider_id) |
| 87 | end |
| 88 | |
| 89 | def add_artist_provider(artist, song_provider_id) |
| 90 | genres = artist['genres'].nil? ? '' : artist['genres'].join(',') |
| 91 | |
| 92 | artist = ArtistProvider.new(user_id: @user.id, provider_id: artist['id'], |
| 93 | provider_type: provider_type, |
| 94 | name: artist['name'], genres: genres) |
| 95 | return unless artist.save |
| 96 | |
| 97 | add_song_artist_if_needed(song_provider_id, artist.id) |
| 98 | end |
| 99 | |
| 100 | def provider_type |
| 101 | ArtistProvider.provider_types[:spotify] |
| 102 | end |
| 103 | end |