helliun commited on
Commit
7658165
·
verified ·
1 Parent(s): 155b13a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +290 -0
app.py ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import re
4
+ import csv
5
+ import pandas as pd
6
+
7
+
8
+ def update_scores(winner, loser, k_factor=100):
9
+ score_difference = int(k_factor/(winner/loser))
10
+ winner += score_difference
11
+ loser -= score_difference
12
+ return winner, loser
13
+
14
+ def vote_startup(songs_df, previews_df):
15
+ try:
16
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
17
+ except:
18
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
19
+ if len(songs_df)>0:
20
+ slice_size = 4
21
+ slice = int(len(songs_df)/slice_size)
22
+ sample = songs_df[slice:(slice_size-1)*slice].sample(frac=1).iloc[0]
23
+ song_title, artist = sample["song_title"], sample["artist"]
24
+ if len(songs_df) > 1:
25
+ # Randomly select a song to compare with
26
+ sample = songs_df.sample(frac=1)
27
+ comparison_song = sample.iloc[0]
28
+ if comparison_song['song_title'] == song_title and comparison_song['artist'] == artist:
29
+ comparison_song = sample.iloc[1]
30
+ first_df = songs_df[songs_df["song_title"]==song_title][songs_df["artist"]==artist]
31
+ first_string = first_df["song_title"].tolist()[0]+" - "+first_df["artist"].tolist()[0]
32
+ second_df = comparison_song
33
+ second_string = second_df["song_title"]+" - "+second_df["artist"]
34
+ return f"Do you like '{artist} - {song_title}' better than '{comparison_song['artist']} - {comparison_song['song_title']}'?", first_string, second_string, display_rankings(songs_df), previews_df[previews_df["song_title"]==song_title].iloc[0]["preview_url"],previews_df[previews_df["song_title"]==comparison_song['song_title']].iloc[0]["preview_url"]
35
+ else:
36
+ return "Add some songs to start voting!", "", "", display_rankings(songs_df)
37
+
38
+ def clean_string(string):
39
+ string = string.strip().replace(" "," ").lower()
40
+ string = " ".join([x[0].upper()+x[1:] for x in string.split()])
41
+ return string
42
+
43
+ def add_and_compare(artist, song_title, songs_df):
44
+ try:
45
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
46
+ except:
47
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
48
+ if artist != "" and song_title != "":
49
+ artist = clean_string(artist)
50
+ song_title = clean_string(song_title)
51
+ new_song = pd.DataFrame({'artist': [artist], 'song_title': [song_title], 'elo_score': [1000]})
52
+ songs_df = pd.concat([songs_df, new_song], ignore_index=True)
53
+ songs_df.to_csv("songs_df.csv")
54
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
55
+ return "", "", display_rankings(songs_df)
56
+
57
+ # Function to update Elo ratings based on user's choice
58
+ def update_ratings_pos(first_string, second_string, songs_df, previews_df):
59
+ try:
60
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
61
+ except:
62
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
63
+ if len(songs_df)==0:
64
+ return "Add some songs to start voting!", "", "", display_rankings(songs_df)
65
+ if first_string != "":
66
+ songs_df["combined"] = songs_df["song_title"] + " - " + songs_df["artist"]
67
+ loser = songs_df[songs_df["combined"] == second_string]
68
+ winner = songs_df[songs_df["combined"] == first_string]
69
+ # Update Elo scores
70
+ winner_score, loser_score = update_scores(winner['elo_score'].values[0], loser['elo_score'].values[0])
71
+ songs_df.at[winner.index[0], 'elo_score'] = winner_score
72
+ songs_df.at[loser.index[0], 'elo_score'] = loser_score
73
+
74
+ songs_df = songs_df.sort_values(by='elo_score', ascending=False)
75
+ songs_df.to_csv("songs_df.csv")
76
+ slice_size = 4
77
+ slice = int(len(songs_df)/slice_size)
78
+ sample = songs_df[slice:(slice_size-1)*slice].sample(frac=1).iloc[0]
79
+ song_title, artist = sample["song_title"], sample["artist"]
80
+ if len(songs_df) > 1:
81
+ # Randomly select a song to compare with
82
+ sample = songs_df.sample(frac=1)
83
+ comparison_song = sample.iloc[0]
84
+ if comparison_song['song_title'] == song_title and comparison_song['artist'] == artist:
85
+ comparison_song = sample.iloc[1]
86
+ first_df = songs_df[songs_df["song_title"]==song_title][songs_df["artist"]==artist]
87
+ first_string = first_df["song_title"].tolist()[0]+" - "+first_df["artist"].tolist()[0]
88
+ second_df = comparison_song
89
+ second_string = second_df["song_title"]+" - "+second_df["artist"]
90
+ return f"Do you like '{artist} - {song_title}' better than '{comparison_song['artist']} - {comparison_song['song_title']}'?", first_string, second_string, display_rankings(songs_df), previews_df[previews_df["song_title"]==song_title].iloc[0]["preview_url"],previews_df[previews_df["song_title"]==comparison_song['song_title']].iloc[0]["preview_url"]
91
+ else:
92
+ return "Add some songs to start voting!", "", "", display_rankings(songs_df)
93
+
94
+ # Function to update Elo ratings based on user's choice
95
+ def update_ratings_neg(first_string, second_string, songs_df, previews_df):
96
+ try:
97
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
98
+ except:
99
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
100
+ if len(songs_df)==0:
101
+ return "Add some songs to start voting!", "", "", display_rankings(songs_df)
102
+ if first_string != "":
103
+ songs_df["combined"] = songs_df["song_title"] + " - " + songs_df["artist"]
104
+ loser = songs_df[songs_df["combined"] == first_string]
105
+ winner = songs_df[songs_df["combined"] == second_string]
106
+
107
+ # Update Elo scores
108
+ winner_score, loser_score = update_scores(winner['elo_score'].values[0], loser['elo_score'].values[0])
109
+ songs_df.at[winner.index[0], 'elo_score'] = winner_score
110
+ songs_df.at[loser.index[0], 'elo_score'] = loser_score
111
+
112
+ songs_df = songs_df.sort_values(by='elo_score', ascending=False)
113
+ songs_df.to_csv("songs_df.csv")
114
+ slice_size = 4
115
+ slice = int(len(songs_df)/slice_size)
116
+ sample = songs_df[slice:(slice_size-1)*slice].sample(frac=1).iloc[0]
117
+ song_title, artist = sample["song_title"], sample["artist"]
118
+ if len(songs_df) > 1:
119
+ # Randomly select a song to compare with
120
+ sample = songs_df.sample(frac=1)
121
+ comparison_song = sample.iloc[0]
122
+ if comparison_song['song_title'] == song_title and comparison_song['artist'] == artist:
123
+ comparison_song = sample.iloc[1]
124
+ first_df = songs_df[songs_df["song_title"]==song_title][songs_df["artist"]==artist]
125
+ first_string = first_df["song_title"].tolist()[0]+" - "+first_df["artist"].tolist()[0]
126
+ second_df = comparison_song
127
+ second_string = second_df["song_title"]+" - "+second_df["artist"]
128
+ return f"Do you like '{artist} - {song_title}' better than '{comparison_song['artist']} - {comparison_song['song_title']}'?", first_string, second_string, display_rankings(songs_df), previews_df[previews_df["song_title"]==song_title].iloc[0]["preview_url"],previews_df[previews_df["song_title"]==comparison_song['song_title']].iloc[0]["preview_url"]
129
+ else:
130
+ return "Add some songs to start voting!", "", "", display_rankings(songs_df)
131
+
132
+ def display_rankings(songs_df=pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])):
133
+ songs_df = songs_df.sort_values(by='elo_score', ascending=False)
134
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
135
+ songs_df.to_csv("songs_df.csv")
136
+ return songs_df
137
+
138
+ def export_csv(songs_df, previews_df):
139
+ # Function to export DataFrame to CSV
140
+ save_df = songs_df
141
+ save_df["preview_url"] = [previews_df[previews_df["artist"]==artist][previews_df["song_title"]==song_title].iloc[0]["preview_url"] for artist, song_title in zip(songs_df["artist"].tolist(),songs_df["song_title"].tolist())]
142
+ save_df.to_csv("songs_df.csv")
143
+ return "songs_df.csv"
144
+
145
+ def import_csv(file, songs_df, previews_df):
146
+ if file is not None:
147
+ #file_content = file.decode('utf-8')
148
+ new_df = pd.read_csv(file)
149
+ try:
150
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
151
+ previews_df = previews_df[["elo_score", "artist", "song_title", "preview_url"]]
152
+ except:
153
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
154
+ previews_df = pd.DataFrame(columns=["elo_score", "artist", "song_title", "preview_url"])
155
+ new_df = new_df[["elo_score", "artist", "song_title", "preview_url"]]
156
+ previews_df = pd.concat([previews_df,new_df])
157
+ new_df = new_df[["elo_score", "artist", "song_title"]]
158
+ songs_df = pd.concat([songs_df,new_df])
159
+
160
+ songs_df = songs_df.drop_duplicates(subset=['artist', 'song_title'])
161
+ previews_df = previews_df.drop_duplicates(subset=['artist', 'song_title'])
162
+ return songs_df, previews_df
163
+
164
+
165
+ # Function to remove a song
166
+ def remove_song(artist, song_title, songs_df):
167
+ # Find and remove the song from the DataFrame
168
+ artist = clean_string(artist)
169
+ song_title = clean_string(song_title)
170
+ songs_df = songs_df[~((songs_df["artist"] == artist) & (songs_df["song_title"] == song_title))]
171
+ return songs_df[["elo_score", "artist", "song_title"]]
172
+
173
+ def reset_rankings(songs_df):
174
+ songs_df["elo_score"] = [1000]*len(songs_df)
175
+ songs_df = songs_df[["elo_score", "artist", "song_title"]]
176
+ return display_rankings(songs_df)
177
+
178
+ def clear_rankings(songs_df):
179
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
180
+ return display_rankings(songs_df)
181
+
182
+
183
+ # theme='Taithrah/Minimal'
184
+ # Gradio interface
185
+ with gr.Blocks(theme=theme) as app:
186
+
187
+ gr.Markdown(
188
+ """## Song Ranker for Spotify
189
+ This tool helps you create **accurate rankings** of songs based on your personal preferences.
190
+ It does this by asking you questions comparing a random pair of songs, and then using your
191
+ answers to calculate Elo scores for ranking. Import songs by pasting a **song, playlist, or album**
192
+ link below and clicking "Add".
193
+ """
194
+ )
195
+
196
+ with gr.Row():
197
+ previews_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title', 'preview_url'])
198
+ previews = gr.DataFrame(value=previews_df, interactive=False, visible=False)
199
+ with gr.Column():
200
+ gr.Markdown(
201
+ """### Vote to Rank
202
+ """
203
+ )
204
+ with gr.Row():
205
+ compare_output = gr.Textbox("Add some songs to start voting!", label="Comparison", interactive=False, scale=3)
206
+ with gr.Row():
207
+ yes_button = gr.Button("Yes", variant="secondary")
208
+ no_button = gr.Button("No", variant="primary")
209
+
210
+ new_vote = gr.Button("New Vote")
211
+ with gr.Row():
212
+ with gr.Column():
213
+ compare_index_1 = gr.Textbox(label="",interactive=False)
214
+ first_song_audio = gr.Audio(label="")
215
+ with gr.Column():
216
+ compare_index_2 = gr.Textbox(label="",interactive=False)
217
+ second_song_audio = gr.Audio(label="")
218
+ with gr.Column():
219
+ gr.Markdown(
220
+ """### Rankings
221
+ """
222
+ )
223
+
224
+ songs_df = pd.DataFrame(columns=['elo_score', 'artist', 'song_title'])
225
+ rankings = gr.DataFrame(value=songs_df, interactive=False, headers=["Score","Artist", "Song"])
226
+
227
+ # gr.Markdown(
228
+ # """### Add Songs from Spotify"""
229
+ # )
230
+
231
+ with gr.Row():
232
+ spotify_link = gr.Textbox(label="Paste Spotify Link", scale=3)
233
+ spotify_button = gr.Button("Add", scale=1)
234
+ with gr.Column(visible=True) as playlist_creation:
235
+ gr.Markdown("""### Create a playlist when you're done!""")
236
+ with gr.Row(visible=True):
237
+ spotify_username = gr.Textbox(label="Spotify Username", visible=False)
238
+ create_playlist_button = gr.Button("Create Spotify Playlist")
239
+ create_playlist_button.click(hide_playlist_button, outputs=[playlist_creation])
240
+ create_playlist_button.click(create_spotify_playlist_from_df, inputs=[rankings, spotify_username, url_params], outputs=[playlist_creation])
241
+
242
+
243
+ with gr.Row():
244
+ artist_input = gr.Textbox(label="Artist")
245
+ song_title_input = gr.Textbox(label="Song Title")
246
+ add_button = gr.Button("Add Song")
247
+
248
+
249
+
250
+ spotify_button.click(get_songs_from_spotify, inputs=[spotify_link, rankings, previews], outputs=[rankings, previews])
251
+
252
+ gr.Markdown(
253
+ """### Remove Songs
254
+ """
255
+ )
256
+ with gr.Row():
257
+ remove_artist_input = gr.Textbox(label="Artist")
258
+ remove_song_title_input = gr.Textbox(label="Song Title")
259
+ remove_button = gr.Button("Remove Song")
260
+ remove_button.click(remove_song, inputs=[remove_artist_input, remove_song_title_input, rankings], outputs=rankings)
261
+
262
+ gr.Markdown(
263
+ """### Import and Export Rankings
264
+ """
265
+ )
266
+ with gr.Row():
267
+
268
+ # Import CSV file to replace the existing DataFrame
269
+ import_button = gr.File(label="Import CSV", file_count="single")
270
+ import_button.change(fn=import_csv, inputs=[import_button, rankings, previews], outputs=[rankings, previews])
271
+
272
+ with gr.Column():
273
+ # Export button to download the DataFrame as CSV
274
+ export_link = gr.File(label="Download CSV", file_count="single")
275
+ export_button = gr.Button("Export as CSV")
276
+ export_button.click(fn=export_csv, inputs=[rankings,previews], outputs=export_link)
277
+
278
+ gr.Markdown("### Reset Data")
279
+ with gr.Row():
280
+ reset_button = gr.Button("Reset Scores")
281
+ reset_button.click(reset_rankings, inputs=[rankings], outputs=rankings)
282
+ clear_button = gr.Button("Clear Table", variant="primary")
283
+ clear_button.click(clear_rankings, inputs=[rankings], outputs=rankings)
284
+
285
+ # add_button.click(add_and_compare, inputs=[artist_input, song_title_input, rankings], outputs=[artist_input, song_title_input, rankings])
286
+ yes_button.click(update_ratings_pos, inputs=[compare_index_1, compare_index_2, rankings, previews], outputs=[compare_output, compare_index_1, compare_index_2, rankings, first_song_audio, second_song_audio])
287
+ no_button.click(update_ratings_neg, inputs=[compare_index_1, compare_index_2, rankings, previews], outputs=[compare_output, compare_index_1, compare_index_2, rankings, first_song_audio, second_song_audio])
288
+ new_vote.click(vote_startup, inputs=[rankings, previews],outputs=[compare_output, compare_index_1, compare_index_2, rankings, first_song_audio, second_song_audio])
289
+
290
+ app.launch(share=False)