-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlastestGuess.py
244 lines (188 loc) · 7.88 KB
/
lastestGuess.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
""" IDEA
Based on https://lastguess.net/ game for Last FM except with a playlist.
User is presented with a single line of lyrics from a song, they must guess the title of the song, artist, and next time.
Things I want to be different from LastGuess
Make the lyrics a bit longer
Allow more configuration of score, etc
"""
# TODO Choose user interface (web?)
# TODO Setup Genius API stuff
from lyricsgenius import Genius
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import os
import random
from flask import Flask, render_template, request, redirect, url_for
from waitress import serve
SPOTIPY_CLIENT_ID = os.getenv('SPOTIFY_CLIENT_ID')
SPOTIFY_SECRET = os.getenv('SPOTIFY_SECRET')
GENIUS_TOKEN = os.getenv('GENIUS_TOKEN')
# User variables (will be added to a setup page)
# Authorise spotify and Genius
scope = "user-library-read"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope,client_id=SPOTIPY_CLIENT_ID,client_secret=SPOTIFY_SECRET,redirect_uri='http://localhost:8080'))
genius = Genius(GENIUS_TOKEN,verbose=False)
# Playlist
def getPlaylist(playlistID):
try:
playlist = sp.playlist(playlist_id=playlistID)
except:
return None
playlist = playlist['tracks']
tracksList = playlist['items']
while playlist['next']: # If more than 100 songs are in playlist, continue collecting.
playlist = sp.next(playlist)
tracksList.extend(playlist['items'])
tracks = []
for track in tracksList:
track = track['track'] # Ignore unneeded information
artists = [artist['name'] for artist in track['artists']]
tracks += [{
'name': track['name'],
'artists': artists,
'album': track['album']['name']
}]
return tracks
class game: # Track a game
def __init__(self,tracks,totalRounds):
self.tracks = tracks.copy()
self.shuffledTracks = self._shuffleTracks(tracks,totalRounds)
self.currentRound = 1
self.currentScore = 0
self.totalRounds = totalRounds
self.guessesPerRound = 3
self.guessCounts = {
'name': 0,
'artist': 0,
'nextLine':0
}
self.correctGuesses = {}
self.buttonText = 'Guess'
def _shuffleTracks(self,tracks,rounds):
random.shuffle(tracks)# Shuffle the tracks
loop = 0
roundData = []
for track in tracks:
if loop < rounds:
lyrics = genius.search_song(title=track['name'],artist=track['artists'][0])
if lyrics != None: # Skip songs where lyrics can't be found.
lyrics = lyrics.lyrics
lyrics = lyrics.split('\n') # Create list of each lyric line
lyrics.pop(0) # Remove Contributors line
lyrics = [line for line in lyrics if line not in [''] and line.startswith(f'See {track['artists'][0]}') == False and line.startswith('(') == False and line.startswith('[') == False] # Remove blank lyrics and things like [Chorus], [Verse 2]
roundData += [{
'name': track['name'],
'artist': track['artists'][0], # For now, only use the first artist
'lyrics': lyrics # Maybe move the song lyric choice to here?
}]
loop += 1
else:
continue
else:
break
return roundData
def createRound(self):
self.guessCounts = {
'name': 0,
'artist': 0,
'nextLine':0
}
self.correctGuesses = {}
self.correctCount == 0
self.currentRoundTrack = self.shuffledTracks[self.currentRound-1]
lyrics = self.currentRoundTrack['lyrics']
totalLyrics = len(lyrics)
ranNum = random.randint(1,totalLyrics-2)
self.currentLyric = lyrics[ranNum]
self.nextLyric = lyrics[ranNum+1]
return self.currentLyric
def guess(self,guessData):
for field, guess in guessData.items():
if field != 'button' and guess != '':
if field == 'nextLine':
if guess.lower() in self.nextLyric.strip(".,`';").lower():
self.currentScore += self.guessesPerRound - self.guessCounts[field]
self.guessCounts[field] = 'Correct'
self.correctGuesses[field] = self.nextLyric
else:
self.guessCounts[field] +=1
else:
if guess.lower() == self.currentRoundTrack[field].lower():
self.currentScore += self.guessesPerRound - self.guessCounts[field]
self.guessCounts[field] = 'Correct'
self.correctGuesses[field] = self.currentRoundTrack[field]
else:
self.guessCounts[field] +=1
if len(self.correctGuesses.keys()) >= 3: # 3 Correct guesses
self.buttonText = 'Next Round'
def giveUp(self): # Add reveal.
self.currentRound+=1
self.createRound()
def roundInformation(self): # Package up round info
roundInfo = {
'playlist': 'NA',
'lyric': self.currentLyric,
'nameAttempt': self.guessCounts['name'],
'artistAttempt': self.guessCounts['artist'],
'nextLineAttempt': self.guessCounts['nextLine'],
'score': self.currentScore,
'currentRound': self.currentRound,
'totalRounds': self.totalRounds,
'allowedGuesses': self.guessesPerRound,
'button': self.buttonText
}
return roundInfo, self.correctGuesses
def createPlayer():
pass
app = Flask(__name__)
@app.route("/")
def home():
try:
reason = request.args['reason']
except:
reason = ''
return render_template('home.html',message=reason)
@app.route("/setup", methods=['GET', 'POST'])
def setupGame():
global setupFormData
if request.method == 'POST':
setupFormData = request.form.to_dict()
if len(setupFormData.keys()) < 2:
return redirect(url_for('.home',reason='please set gamemode and player count'))
elif setupFormData['gameMode'] in ['vs','coop'] and setupFormData['playerCount'].isnumeric():
setupFormData['playerCount'] = int(setupFormData['playerCount']) # Convert to int
return render_template('settings.html',data = setupFormData)
else:
return redirect(url_for('.home',reason='please set player count'))
else:
return redirect(url_for('.home'))
@app.route("/start", methods=['GET', 'POST'])
def start():
global setupFormData
if request.method == 'POST':
formData = request.form.to_dict()
for player in range(0, setupFormData['playerCount']):
playerTracks = getPlaylist(formData['playlistID'])
if playerTracks == None:
return redirect(url_for('.home',reason='Invalid Playlist ID'))
p1 = game(playerTracks,5)
p1.createRound()
roundInfo = p1.roundInformation()
return render_template('game.html',roundData = roundInfo[0],correctGuesses=roundInfo[1])
else:
return redirect(url_for('.home',reason=''))
@app.route("/guess", methods=['POST'])
def guess():
global p1
formData = request.form.to_dict()
if formData['button'] == 'Guess':
p1.guess(formData)
elif formData['button'] == 'Next Round':
p1.giveUp()
else:
p1.giveUp()
roundInfo = p1.roundInformation()
return render_template('game.html',roundData = roundInfo[0],correctGuesses=roundInfo[1])
# Start webserver
if __name__ == '__main__':
serve(app, host = 'localhost', port=8888)