mirror of
https://github.com/Xevion/v1.xevion.dev.git
synced 2025-12-15 04:13:44 -06:00
PyCharm grand repo wide reformat with black formatter
This commit is contained in:
@@ -4,34 +4,36 @@ import os
|
||||
import sys
|
||||
|
||||
# Path to API Credentials file
|
||||
PATH = os.path.join(sys.path[0], 'auth.json')
|
||||
PATH = os.path.join(sys.path[0], "auth.json")
|
||||
|
||||
# Ensure the file exists, if not, generate one and error with a reason
|
||||
if not os.path.exists(PATH):
|
||||
with open(PATH, 'w') as file:
|
||||
with open(PATH, "w") as file:
|
||||
# Dump a pretty-printed dictionary with default values
|
||||
json.dump(
|
||||
{
|
||||
'USERNAME': 'Your Username Here',
|
||||
'CLIENT_ID': 'Your Client ID Here',
|
||||
'CLIENT_SECRET': 'Your Client Secret Here',
|
||||
'REDIRECT_URI': 'Your Redirect URI Callback Here',
|
||||
'SCOPE': ['Your Scopes Here']
|
||||
"USERNAME": "Your Username Here",
|
||||
"CLIENT_ID": "Your Client ID Here",
|
||||
"CLIENT_SECRET": "Your Client Secret Here",
|
||||
"REDIRECT_URI": "Your Redirect URI Callback Here",
|
||||
"SCOPE": ["Your Scopes Here"],
|
||||
},
|
||||
file,
|
||||
indent=3
|
||||
indent=3,
|
||||
)
|
||||
# Error critically, then exit
|
||||
logging.critical("No \'auth.json\' file detected, one has been created for you")
|
||||
logging.critical("Please fill out with your Spotify credentials, and then restart the program")
|
||||
logging.critical("No 'auth.json' file detected, one has been created for you")
|
||||
logging.critical(
|
||||
"Please fill out with your Spotify credentials, and then restart the program"
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
# Open and parse file
|
||||
FILE = json.load(open(PATH, 'r'))
|
||||
FILE = json.load(open(PATH, "r"))
|
||||
|
||||
# Load all configuration variables
|
||||
USERNAME = FILE['USERNAME']
|
||||
CLIENT_ID = FILE['CLIENT_ID']
|
||||
CLIENT_SECRET = FILE['CLIENT_SECRET']
|
||||
REDIRECT_URI = FILE['REDIRECT_URI']
|
||||
SCOPE = ' '.join(FILE['SCOPE'])
|
||||
USERNAME = FILE["USERNAME"]
|
||||
CLIENT_ID = FILE["CLIENT_ID"]
|
||||
CLIENT_SECRET = FILE["CLIENT_SECRET"]
|
||||
REDIRECT_URI = FILE["REDIRECT_URI"]
|
||||
SCOPE = " ".join(FILE["SCOPE"])
|
||||
|
||||
@@ -11,7 +11,7 @@ from . import pull
|
||||
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.info('Pulling data from Spotify')
|
||||
logging.info("Pulling data from Spotify")
|
||||
refresh()
|
||||
process.main()
|
||||
|
||||
@@ -19,14 +19,20 @@ def main():
|
||||
# Refreshes tracks from files if the token from Spotipy has expired,
|
||||
# thus keeping us up to date in most cases while keeping rate limits
|
||||
def refresh():
|
||||
file_path = os.path.join(sys.path[0], f'.cache-{auth.USERNAME}')
|
||||
file_path = os.path.join(sys.path[0], f".cache-{auth.USERNAME}")
|
||||
if os.path.exists(file_path):
|
||||
cache = json.load(open(file_path, 'r'))
|
||||
if True or time.time() > cache['expires_at']:
|
||||
logging.info('Refreshing Spotify data by pulling tracks, this may take a moment.')
|
||||
cache = json.load(open(file_path, "r"))
|
||||
if True or time.time() > cache["expires_at"]:
|
||||
logging.info(
|
||||
"Refreshing Spotify data by pulling tracks, this may take a moment."
|
||||
)
|
||||
pull.main()
|
||||
else:
|
||||
logging.info('Spotify data deemed to be recent enough (under {} seconds old)'.format(cache['expires_in']))
|
||||
logging.info(
|
||||
"Spotify data deemed to be recent enough (under {} seconds old)".format(
|
||||
cache["expires_in"]
|
||||
)
|
||||
)
|
||||
else:
|
||||
pull.main()
|
||||
|
||||
|
||||
@@ -9,13 +9,11 @@ import numpy as np
|
||||
|
||||
# Gets all files in tracks folder, returns them in parsed JSON
|
||||
def get_files():
|
||||
folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tracks')
|
||||
folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tracks")
|
||||
files = []
|
||||
for file in os.listdir(folder):
|
||||
with open(os.path.join(os.path.join(folder, file))) as file:
|
||||
files.append(
|
||||
json.load(file)
|
||||
)
|
||||
files.append(json.load(file))
|
||||
return files
|
||||
|
||||
|
||||
@@ -23,17 +21,17 @@ def get_files():
|
||||
def combine_files(files):
|
||||
items = []
|
||||
for file in files:
|
||||
items.extend(file['items'])
|
||||
items.extend(file["items"])
|
||||
return items
|
||||
|
||||
|
||||
# Prints the data in a interesting format
|
||||
def print_data(data):
|
||||
for i, item in enumerate(data):
|
||||
date = dateutil.parser.parse(item['added_at'])
|
||||
explicit = '!' if item['track']['explicit'] else ' '
|
||||
track_name = item['track']['name']
|
||||
artists = ' & '.join(artist['name'] for artist in item['track']['artists'])
|
||||
date = dateutil.parser.parse(item["added_at"])
|
||||
explicit = "!" if item["track"]["explicit"] else " "
|
||||
track_name = item["track"]["name"]
|
||||
artists = " & ".join(artist["name"] for artist in item["track"]["artists"])
|
||||
print('[{}] {} "{}" by {}'.format(date, explicit, track_name, artists))
|
||||
|
||||
|
||||
@@ -41,10 +39,10 @@ def process_data(data):
|
||||
# Process the data by Month/Year, then by Clean/Explicit
|
||||
scores = {}
|
||||
for item in data:
|
||||
date = dateutil.parser.parse(item['added_at']).strftime('%b %Y')
|
||||
date = dateutil.parser.parse(item["added_at"]).strftime("%b %Y")
|
||||
if date not in scores.keys():
|
||||
scores[date] = [0, 0]
|
||||
scores[date][1 if item['track']['explicit'] else 0] += 1
|
||||
scores[date][1 if item["track"]["explicit"] else 0] += 1
|
||||
|
||||
# Create simplified arrays for each piece of data
|
||||
months = list(scores.keys())[::-1]
|
||||
@@ -54,7 +52,7 @@ def process_data(data):
|
||||
explicit.append(item[1])
|
||||
|
||||
# Done processing date properly, start plotting work
|
||||
logging.info('Processed data, creating plot from data')
|
||||
logging.info("Processed data, creating plot from data")
|
||||
# Weird numpy stuff
|
||||
n = len(scores.values())
|
||||
ind = np.arange(n)
|
||||
@@ -63,33 +61,35 @@ def process_data(data):
|
||||
plt.figure(figsize=(10.0, 6.0))
|
||||
# Stacked Bars
|
||||
p1 = plt.bar(ind, explicit, width)
|
||||
p2 = plt.bar(ind, clean, width, bottom=explicit) # bottom= just has the bar sit on top of the explicit
|
||||
p2 = plt.bar(
|
||||
ind, clean, width, bottom=explicit
|
||||
) # bottom= just has the bar sit on top of the explicit
|
||||
# Plot labeling
|
||||
plt.title('Song Count by Clean/Explicit')
|
||||
plt.ylabel('Song Count')
|
||||
plt.xlabel('Month')
|
||||
plt.title("Song Count by Clean/Explicit")
|
||||
plt.ylabel("Song Count")
|
||||
plt.xlabel("Month")
|
||||
plt.xticks(ind, months, rotation=270) # Rotation 90 will have the
|
||||
plt.legend((p1[0], p2[0]), ('Explicit', 'Clean'))
|
||||
plt.legend((p1[0], p2[0]), ("Explicit", "Clean"))
|
||||
fig = plt.gcf() # Magic to save to image and then show
|
||||
|
||||
# Save the figure, overwriting anything in your way
|
||||
logging.info('Saving the figure to the \'export\' folder')
|
||||
export_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'export')
|
||||
logging.info("Saving the figure to the 'export' folder")
|
||||
export_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), "export")
|
||||
if not os.path.exists(export_folder):
|
||||
os.makedirs(export_folder)
|
||||
plt.tight_layout()
|
||||
fig.savefig(
|
||||
os.path.join(
|
||||
export_folder,
|
||||
'export'
|
||||
"export"
|
||||
# datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
|
||||
),
|
||||
dpi=100,
|
||||
quality=95
|
||||
quality=95,
|
||||
)
|
||||
|
||||
# Finally show the figure to
|
||||
logging.info('Showing plot to User')
|
||||
# Finally show the figure to
|
||||
logging.info("Showing plot to User")
|
||||
# plt.show()
|
||||
|
||||
# Copy the figure to your clipboard to paste in Excel
|
||||
@@ -101,10 +101,17 @@ def process_data(data):
|
||||
# Will paste into Excel very easily
|
||||
def copy(months, clean, explicit):
|
||||
from pyperclip import copy
|
||||
top = 'Period\tClean\tExplicit\n'
|
||||
copy(top + '\n'.join([
|
||||
f'{item[0]}\t{item[1]}\t{item[2]}' for item in zip(months, clean, explicit)
|
||||
]))
|
||||
|
||||
top = "Period\tClean\tExplicit\n"
|
||||
copy(
|
||||
top
|
||||
+ "\n".join(
|
||||
[
|
||||
f"{item[0]}\t{item[1]}\t{item[2]}"
|
||||
for item in zip(months, clean, explicit)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -114,7 +121,10 @@ def main():
|
||||
logging.info(f"Read and parse {len(files)} track files")
|
||||
logging.info("Combining into single track file for ease of access")
|
||||
data = combine_files(files)
|
||||
data.sort(key=lambda item: dateutil.parser.parse(item['added_at']).timestamp(), reverse=True)
|
||||
logging.info(f'File combined with {len(data)} items')
|
||||
logging.info('Processing file...')
|
||||
data.sort(
|
||||
key=lambda item: dateutil.parser.parse(item["added_at"]).timestamp(),
|
||||
reverse=True,
|
||||
)
|
||||
logging.info(f"File combined with {len(data)} items")
|
||||
logging.info("Processing file...")
|
||||
process_data(data)
|
||||
|
||||
@@ -13,54 +13,58 @@ from . import auth
|
||||
def main():
|
||||
# Get Authorization
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.info('Authorizing with Spotify via Spotipy')
|
||||
logging.warning('May require User Interaction to authenticate properly!')
|
||||
logging.info("Authorizing with Spotify via Spotipy")
|
||||
logging.warning("May require User Interaction to authenticate properly!")
|
||||
token = util.prompt_for_user_token(
|
||||
username=auth.USERNAME,
|
||||
scope=auth.SCOPE,
|
||||
client_id=auth.CLIENT_ID,
|
||||
client_secret=auth.CLIENT_SECRET,
|
||||
redirect_uri=auth.REDIRECT_URI
|
||||
redirect_uri=auth.REDIRECT_URI,
|
||||
)
|
||||
sp = spotipy.Spotify(auth=token)
|
||||
logging.info('Authorized with Spotify via Spotipy')
|
||||
logging.info("Authorized with Spotify via Spotipy")
|
||||
|
||||
tracks_folder = os.path.join(os.path.dirname(__file__), 'tracks')
|
||||
logging.warning('Clearing all files in tracks folder for new files')
|
||||
tracks_folder = os.path.join(os.path.dirname(__file__), "tracks")
|
||||
logging.warning("Clearing all files in tracks folder for new files")
|
||||
if os.path.exists(tracks_folder):
|
||||
shutil.rmtree(tracks_folder) # Delete folder and all contents (old track files)
|
||||
os.makedirs(tracks_folder) # Recreate the folder just deleted
|
||||
logging.info('Cleared folder, ready to download new track files')
|
||||
logging.info("Cleared folder, ready to download new track files")
|
||||
|
||||
curoffset, curlimit = 0, 50
|
||||
while curoffset >= 0:
|
||||
# Request and identify what was received
|
||||
logging.info('Requesting {} to {}'.format(curoffset, curoffset + curlimit))
|
||||
logging.info("Requesting {} to {}".format(curoffset, curoffset + curlimit))
|
||||
response = sp.current_user_saved_tracks(limit=curlimit, offset=curoffset)
|
||||
received = len(response['items'])
|
||||
logging.info('Received {} to {}'.format(curoffset, curoffset + received))
|
||||
received = len(response["items"])
|
||||
logging.info("Received {} to {}".format(curoffset, curoffset + received))
|
||||
# Create path/filename
|
||||
filename = f'saved-tracks-{curoffset}-{curoffset + received}.json'
|
||||
filename = f"saved-tracks-{curoffset}-{curoffset + received}.json"
|
||||
filepath = os.path.join(tracks_folder, filename)
|
||||
# Save track file
|
||||
with open(filepath, 'w+') as file:
|
||||
with open(filepath, "w+") as file:
|
||||
json.dump(response, file)
|
||||
logging.info('Saved at "{}" ({})'.format(
|
||||
f'\\tracks\\{filename}',
|
||||
size(os.path.getsize(filepath)))
|
||||
logging.info(
|
||||
'Saved at "{}" ({})'.format(
|
||||
f"\\tracks\\{filename}", size(os.path.getsize(filepath))
|
||||
)
|
||||
)
|
||||
# Decide whether we have received all possible tracks
|
||||
if received < curlimit:
|
||||
logging.info('Requested and saved {} tracks split over {} files ({})'.format(
|
||||
curoffset + received,
|
||||
len(os.listdir(tracks_folder)),
|
||||
size(
|
||||
sum(
|
||||
os.path.getsize(os.path.join(tracks_folder, file)) for file in os.listdir(tracks_folder)
|
||||
logging.info(
|
||||
"Requested and saved {} tracks split over {} files ({})".format(
|
||||
curoffset + received,
|
||||
len(os.listdir(tracks_folder)),
|
||||
size(
|
||||
sum(
|
||||
os.path.getsize(os.path.join(tracks_folder, file))
|
||||
for file in os.listdir(tracks_folder)
|
||||
),
|
||||
system=alternative,
|
||||
),
|
||||
system=alternative
|
||||
)
|
||||
))
|
||||
)
|
||||
break
|
||||
# Continuing, so increment offset
|
||||
curoffset += curlimit
|
||||
|
||||
Reference in New Issue
Block a user