-
Notifications
You must be signed in to change notification settings - Fork 1
/
machine.py
143 lines (113 loc) · 6.54 KB
/
machine.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
import os
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import requests
from bs4 import BeautifulSoup
SPOTIPY_CLIENT_ID = os.environ.get('SPOTIPY_CLIENT_ID')
SPOTIPY_CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
SPOTIPY_REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')
def welcome_message():
msg = '''\033[1;33;40m
WELCOME TO...
.___________. __ __ _______
| || | | | | ____|
______ `---| |----`| |__| | | |__
|______| | | | __ | | __|
| | | | | | | |____
|__| |__| |__| |_______|
.___ ___. __ __ _______. __ ______ .___________. __ .___ ___. _______
| \/ | | | | | / || | / | | || | | \/ | | ____|
| \ / | | | | | | (----`| | | ,----' `---| |----`| | | \ / | | |__
| |\/| | | | | | \ \ | | | | | | | | | |\/| | | __|
| | | | | `--' | .----) | | | | `----. | | | | | | | | | |____
|__| |__| \______/ |_______/ |__| \______| |__| |__| |__| |__| |_______|
.___ ___. ___ ______ __ __ __ .__ __. _______
| \/ | / \ / || | | | | | | \ | | | ____|
| \ / | / ^ \ | ,----'| |__| | | | | \| | | |__ ______
| |\/| | / /_\ \ | | | __ | | | | . ` | | __| |______|
| | | | / _____ \ | `----.| | | | | | | |\ | | |____
|__| |__| /__/ \__\ \______||__| |__| |__| |__| \__| |_______|
Type a valid date in time and we'll create you a Spotify playlist with the top songs
playing in the world in that moment.
OPTIONS:
[1] - I only want the songs by the original performers (- less songs)
[2] - I don't care who performs it (+ more songs)
----------------------------------------------------------------------
Let's go for a musical ride.
\033[m'''
print(msg)
def bye_message():
print('\033[33m\nThanks for trying us out!\nTime to take off now.\nSee you next time!\033[m')
def is_date_format_invalid(answer_date_split):
# The idea here is not to treat an invalid date format and keep asking the user for valid input
if len(answer_date_split) != 3:
return True
if len(answer_date_split) == 3:
first_item_is_numeric = True if answer_date_split[0].isnumeric() and len(
answer_date_split[0]) == 4 else False
second_item_is_numeric = True if answer_date_split[1].isnumeric() and len(
answer_date_split[1]) == 2 else False
third_item_is_numeric = True if answer_date_split[2].isnumeric() and len(
answer_date_split[2]) == 2 else False
if first_item_is_numeric and second_item_is_numeric and third_item_is_numeric:
return False
return True
def send_request_to_billboard(date):
url_billboard = f'https://www.billboard.com/charts/hot-100/{date}/'
response = requests.get(url=url_billboard, allow_redirects=False)
if response.status_code != 200:
raise Exception(f'Error. We expeected a status_code value of 200, but we got {response.status_code} instead.'
f'.\nPlease, be sure to check if the URL is active and the date provided is valid.')
return response
def grab_music_titles_and_artist_names(response):
soup = BeautifulSoup(response.content, 'lxml')
containers = soup.find_all('div', {'class': 'o-chart-results-list-row-container'})
if containers is None:
raise Exception("Error. Please verify if the tags for each container exist in the response.")
songs_and_artists = []
for i, container in enumerate(containers):
i += 1
title_tag = container.find('h3', {'id': 'title-of-a-story'})
artist_tag = title_tag.find_next_sibling()
song_title = title_tag.text.strip()
artist_name = artist_tag.text.strip()
songs_and_artists.append((song_title, artist_name))
# print(f'{i}) {song_title.upper()} - {artist_name}')
return songs_and_artists
def spotify_create_playlist(answer_date='1998-11-21', songs_and_artists=None, option='1'):
playlist_name = f"({answer_date}) Billboard top charts"
year = answer_date.split('-')[0]
scope = 'playlist-modify-private'
sp = spotipy.Spotify(
client_credentials_manager=SpotifyOAuth(
scope=scope,
client_id=SPOTIPY_CLIENT_ID,
client_secret=SPOTIPY_CLIENT_SECRET,
redirect_uri=SPOTIPY_REDIRECT_URI,
show_dialog=True,
cache_path="token.txt")
)
user_id = sp.current_user()['id']
print(f"\n\033[1;32mWe're at Spotify.\033[m\nLet's start the creation of your playlist...\n")
spotify_uris = []
for song_title, artist_name in songs_and_artists:
if option == '1':
spotify_results = sp.search(q=f"track:{song_title} artist:{artist_name}", type="track")
else:
spotify_results = sp.search(q=f"track:{song_title} year:{year}", type="track")
try:
uri = spotify_results['tracks']['items'][0]['uri']
spotify_uris.append(uri)
except:
print(f"\033[31mWe're skipping song \033[1;37;40m'{song_title.upper()}'\033[0m \033[31mbecause "
f"we were unable to find it. Sorry.\033[m")
if option == '1':
playlist_name = f"({answer_date}) Billboard top charts (original performers)"
playlist = sp.user_playlist_create(user=user_id,
name=playlist_name,
public=False,
description='''Created by "The Music Time Machine" developed by
Barbara Calderon (github.com/barbaracalderon) in january, 2023.''')
playlist_id = playlist["id"]
sp.playlist_add_items(playlist_id=playlist_id, items=spotify_uris)
print(f"\nDone.\n\033[1;32mPlaylist created successfully.\033[m")