feature/share-libs
rb 166 lines 5.45 KB
Raw
1 # frozen_string_literal: true
2
3 module Api
4 module V1
5 class SongBridgeController < ApiController
6 before_action :authenticate_user!, only: %i[add_song_provider vote]
7
8 def add_song_provider
9 find_song_provider
10 if @song_provider.present?
11 return render json: { code: 200, message: 'Song provider already exists' }, status: :ok
12 end
13
14 find_or_create_base_song
15 create_song_provider
16 render json: { code: 200, message: 'Song provider created', song: @song }, status: :created
17 end
18
19 def find_audio
20 # Get the Spotify track ID from the URL
21 song_provider = SongProvider.find(params[:id])
22 song = song_provider.song || Song.create(name: song_provider.name, user_id: song_provider.user_id)
23 # Find available Spotify token
24 authorization = User.joins(:user_setting).where(user_setting: { allowed_use_spotify_token: true }).first.spotify
25 # If no available Spotify token, return
26 return render json: { error: 'No available Spotify token' }, status: :unprocessable_entity unless authorization
27
28 # Create Spotify client
29 client = SpotifyClient.new(authorization)
30 # Call Spotify API
31 response = client.get_track(song_provider.provider_id)
32 # Parse response
33 spotify_track = JSON.parse(response.body)
34 p spotify_track
35 images = []
36 images = spotify_track['album']['images'] if spotify_track['error'].nil?
37 album_name = ''
38 album_name = spotify_track['album']['name'] if spotify_track['error'].nil?
39
40 youtubes = SongProvider
41 .where(
42 'lower(description) LIKE ? AND provider_type = 1',
43 "%#{song_provider.name}%"
44 )
45 .limit(10)
46 .as_json(only: %i[id name provider_id image_url])
47
48 render json: {
49 code: 200,
50 name: song_provider.name,
51 album_name: album_name,
52 images: images,
53 items: youtubes || []
54 }
55 end
56
57 def vote
58 song_provider = SongProvider.find_by(id: params[:provider_id])
59 insert_or_remove_vote
60
61 render json: { code: 200, message: 'Song provider found.', song_provider: song_provider,
62 votes: song_provider.song_provider_vote },
63 status: :ok
64 end
65
66 def detail
67 @provider = SongProvider.find_by(id: params[:id], provider_type: :youtube)
68 return render json: { code: 404, message: 'Song provider not found' }, status: :not_found unless @provider
69
70 render_song_provider
71 end
72
73 def carousel
74 @songs = SongProvider.where(provider_type: :youtube).order(Arel.sql('random()')).limit(15)
75 render json: {
76 code: 200,
77 message: 'OK',
78 audio_files: @songs
79 }
80 end
81
82 def top_votes
83 # Find most voted song providers
84 @songs = SongProvider.joins(:song_provider_vote).group(:id).order('count(song_provider_votes.id) DESC').limit(20)
85 render json: {
86 code: 200,
87 message: 'OK',
88 audio_files: @songs
89 }
90 end
91
92 def ready_to_play
93 # Find all songs that are ready to play
94 @songs = SongProvider.where(audio_file: { status: :done }, status: :published).joins(:audio_file)
95 render json: {
96 code: 200,
97 message: 'OK',
98 audio_files: @songs
99 }
100 end
101
102 private
103
104 def find_song_provider
105 provider_id = params[:provider_id]
106 provider = SongProvider.provider_types[params[:provider]]
107 @song_provider = SongProvider.find_by(provider_id: provider_id, provider_type: provider)
108 end
109
110 def create_song_provider
111 provider_id = params[:provider_id]
112 name = params[:name]
113 provider = SongProvider.provider_types[params[:provider]]
114 @song_provider = SongProvider.create(
115 provider_id: provider_id,
116 name: name,
117 provider_type: provider,
118 user_id: current_user.id,
119 song_id: @song.id
120 )
121 end
122
123 def find_or_create_base_song
124 reference = SongProvider.find(params[:reference_id])
125 @song = if reference.song.present?
126 reference.song
127 else
128 Song.create(
129 name: reference.name,
130 user_id: current_user.id
131 )
132 end
133 end
134
135 def insert_or_remove_vote
136 vote_type = params[:vote_type]
137 provider_id = params[:provider_id]
138 # This should be validated in the front end
139 @vote = SongProviderVote.find_by(user_id: current_user.id, song_provider_id: provider_id)
140 # If vote exists, remove it.
141 if @vote.present?
142 @vote.destroy
143 else
144 @vote = SongProviderVote.new(user_id: current_user.id, song_provider_id: provider_id, vote_type: vote_type)
145 @vote.save
146 end
147 end
148
149 def render_song_provider
150 render json: { code: 200, message: 'Song provider found', song_provider: @provider,
151 votes: @provider.song_provider_vote }, status: :ok
152 end
153
154 def process_song_provider
155 @audio_file = AudioFile.new(status: :downloading, song_provider_id: @provider.id)
156 @audio_file.save
157
158 YoutubeToAudioJob.perform_later(@provider.id)
159
160 # Update provider
161 @provider = @audio_file.song_provider
162 render_song_provider
163 end
164 end
165 end
166 end