python:deezer-album-tracker
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
python:deezer-album-tracker [2024/03/28 17:03] – Wulf Rajek | python:deezer-album-tracker [2024/04/21 20:05] (current) – Wulf Rajek | ||
---|---|---|---|
Line 2: | Line 2: | ||
This script uses the deezer public api to provide a list of albums released the past half year of artists in the configuration file. Configuration file will be created if it doesn' | This script uses the deezer public api to provide a list of albums released the past half year of artists in the configuration file. Configuration file will be created if it doesn' | ||
+ | |||
+ | Depending on network speed and amount of albums per artist and due to deezer API rate limit of max 50 requests per 5 seconds, querying 180 days for 235 artists takes about 1:45 minutes. | ||
Prerequisites for fuzzy search: | Prerequisites for fuzzy search: | ||
Line 8: | Line 10: | ||
Usage: | Usage: | ||
< | < | ||
- | usage: dat.py [-h] [--list] [--add ARTIST_NAME] [--delete SEARCH_TERM] [--email] | + | usage: dat.py [-h] [--list] [--days DAYS] [--add ARTIST_NAME] [--delete SEARCH_TERM] [--email] |
Deezer Album Tracker | Deezer Album Tracker | ||
Line 15: | Line 17: | ||
-h, --help | -h, --help | ||
--list | --list | ||
+ | --days DAYS | ||
--add ARTIST_NAME | --add ARTIST_NAME | ||
--delete SEARCH_TERM | --delete SEARCH_TERM | ||
Line 22: | Line 25: | ||
Example output: | Example output: | ||
< | < | ||
- | $ ./dat.py | + | $ / |
- | Albums released in the past 6 months: | + | Albums released in the past 7 days: |
- | Release Date: 2024-01-12 | + | |
- | Artist: | + | Release Date: 2024-04-19 |
- | Album Name: Scars (feat. | + | Artist: |
+ | Album Name: Better Days (feat. | ||
+ | Link: https:// | ||
+ | |||
+ | Release Date: 2024-04-19 | ||
+ | Artist: Distilled Harmony | ||
+ | Album Name: Nova (3 tracks) | ||
+ | Link: https:// | ||
- | Release Date: 2023-11-03 | + | Release Date: 2024-04-19 |
- | Artist: | + | Artist: |
- | Album Name: Counterfeit Countdown | + | Album Name: THE TORTURED POETS DEPARTMENT [EXPLICIT] (16 tracks) |
+ | Link: https:// | ||
- | Release Date: 2023-10-31 | ||
- | Artist: Papa Roach | ||
- | Album Name: Leave a Light On (Talk Away The Dark) | ||
</ | </ | ||
Line 40: | Line 48: | ||
<code json config.json> | <code json config.json> | ||
{ | { | ||
+ | " | ||
+ | " | ||
+ | }, | ||
" | " | ||
" | " | ||
Line 60: | Line 71: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | |||
+ | To add artists in bulk, the simplest way is to create a text file with an artist on each line, then use the following bash command to let dat.py search deezer for the id and add it to the config file: | ||
+ | < | ||
<code python dat.py> | <code python dat.py> | ||
# | # | ||
+ | import ssl | ||
import smtplib | import smtplib | ||
from email.mime.multipart import MIMEMultipart | from email.mime.multipart import MIMEMultipart | ||
Line 70: | Line 86: | ||
import json | import json | ||
from datetime import datetime, timedelta | from datetime import datetime, timedelta | ||
+ | import time | ||
import argparse | import argparse | ||
- | from fuzzywuzzy import fuzz | + | from fuzzywuzzy import fuzz, process |
- | from fuzzywuzzy import | + | |
import os | import os | ||
# Constants for file paths | # Constants for file paths | ||
- | CONFIG_FILE | + | CONFIG_FILENAME |
+ | SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
+ | CONFIG_FILE = os.path.join(SCRIPT_DIR, | ||
def load_config(): | def load_config(): | ||
Line 82: | Line 101: | ||
# Create default config file if it doesn' | # Create default config file if it doesn' | ||
default_config = { | default_config = { | ||
+ | " | ||
+ | " | ||
+ | }, | ||
" | " | ||
" | " | ||
Line 97: | Line 119: | ||
with open(CONFIG_FILE, | with open(CONFIG_FILE, | ||
return json.load(config_file) | return json.load(config_file) | ||
+ | |||
def save_config(config): | def save_config(config): | ||
Line 102: | Line 125: | ||
json.dump(config, | json.dump(config, | ||
- | def send_email(subject, | + | |
+ | def send_email(body): | ||
config = load_config() | config = load_config() | ||
email_config = config.get(' | email_config = config.get(' | ||
Line 113: | Line 137: | ||
sender_email = email_config.get(' | sender_email = email_config.get(' | ||
sender_password = email_config.get(' | sender_password = email_config.get(' | ||
+ | email_subject = config.get(' | ||
msg = MIMEMultipart() | msg = MIMEMultipart() | ||
msg[' | msg[' | ||
msg[' | msg[' | ||
- | msg[' | + | msg[' |
body = MIMEText(body) | body = MIMEText(body) | ||
Line 131: | Line 156: | ||
server.login(sender_email, | server.login(sender_email, | ||
server.send_message(msg) | server.send_message(msg) | ||
+ | |||
def get_artist_name(artist_id): | def get_artist_name(artist_id): | ||
Line 139: | Line 165: | ||
return data.get(' | return data.get(' | ||
return '' | return '' | ||
+ | |||
def get_artist_id(artist_name): | def get_artist_id(artist_name): | ||
Line 150: | Line 177: | ||
return None | return None | ||
- | def get_albums(artist_ids): | + | |
+ | def get_albums(artist_ids, lookupdays): | ||
base_url = " | base_url = " | ||
- | | + | |
albums = [] | albums = [] | ||
+ | request_count = 0 | ||
+ | start_time = time.time() | ||
+ | |||
+ | today = datetime.today().strftime(' | ||
for artist_id in artist_ids: | for artist_id in artist_ids: | ||
url = base_url.format(artist_id) | url = base_url.format(artist_id) | ||
response = requests.get(url) | response = requests.get(url) | ||
+ | request_count += 1 | ||
if response.status_code == 200: | if response.status_code == 200: | ||
data = response.json() | data = response.json() | ||
Line 163: | Line 196: | ||
for album in data[' | for album in data[' | ||
release_date = datetime.strptime(album[' | release_date = datetime.strptime(album[' | ||
- | if release_date | + | if (datetime.strptime(earliest_release, |
+ | | ||
+ | trackresponse = requests.get(album[' | ||
+ | request_count += 1 | ||
+ | if trackresponse.status_code == 200: | ||
+ | tracklist = trackresponse.json() | ||
+ | trackamount = tracklist[' | ||
+ | else: | ||
+ | trackamount = 0 | ||
albums.append({ | albums.append({ | ||
' | ' | ||
' | ' | ||
- | ' | + | ' |
+ | ' | ||
+ | ' | ||
+ | ' | ||
}) | }) | ||
+ | |||
+ | # Deezer rate limit is 50 requests / 5 seconds. Limiting to 40/5 here: | ||
+ | # Check if 40 requests have been made in less than 5 seconds | ||
+ | if request_count == 40: | ||
+ | elapsed_time = time.time() - start_time | ||
+ | if elapsed_time < 5: | ||
+ | time.sleep(5 - elapsed_time) | ||
+ | # Reset request count and start time | ||
+ | request_count = 0 | ||
+ | start_time = time.time() | ||
+ | |||
return sorted(albums, | return sorted(albums, | ||
+ | |||
def list_artists(): | def list_artists(): | ||
config = load_config() | config = load_config() | ||
subscribed_artists = config.get(' | subscribed_artists = config.get(' | ||
- | for artist_id, artist_name in subscribed_artists.items(): | + | |
- | print(f" | + | |
+ | print(f" | ||
def add_artist(artist_name): | def add_artist(artist_name): | ||
Line 187: | Line 246: | ||
else: | else: | ||
print(" | print(" | ||
+ | |||
def delete_artist(search_term): | def delete_artist(search_term): | ||
Line 196: | Line 256: | ||
for index, (artist_name, | for index, (artist_name, | ||
print(f" | print(f" | ||
- | | + | |
- | if 0 <= choice_index < len(choices): | + | if choice_input.isnumeric(): |
- | artist_name = choices[choice_index][0] | + | choice_index = int(choice_input) - 1 |
- | artist_id = [key for key, value in subscribed_artists.items() if value == artist_name][0] | + | if 0 <= choice_index < len(choices): |
- | del config[artist_id] | + | artist_name = choices[choice_index][0] |
- | save_config(config) | + | artist_id = [key for key, value in subscribed_artists.items() if value == artist_name][0] |
- | print(f" | + | del config[' |
+ | save_config(config) | ||
+ | print(f" | ||
+ | else: | ||
+ | print(" | ||
else: | else: | ||
- | print(" | + | print(" |
def main(): | def main(): | ||
parser = argparse.ArgumentParser(description=" | parser = argparse.ArgumentParser(description=" | ||
parser.add_argument(" | parser.add_argument(" | ||
+ | parser.add_argument(" | ||
parser.add_argument(" | parser.add_argument(" | ||
parser.add_argument(" | parser.add_argument(" | ||
Line 224: | Line 290: | ||
config = load_config() | config = load_config() | ||
artist_ids = config.get(' | artist_ids = config.get(' | ||
- | albums = get_albums(artist_ids) | + | |
+ | lookupdays = int(args.days) | ||
+ | else: | ||
+ | lookupdays = config.get(' | ||
+ | | ||
- | | + | |
for album in albums: | for album in albums: | ||
- | | + | |
- | | + | |
- | | + | |
- | print() | + | if album[' |
+ | output += " [EXPLICIT]" | ||
+ | if album[' | ||
+ | output += f" ({album[' | ||
+ | if album[' | ||
+ | output += " | ||
+ | output += ")" | ||
+ | | ||
+ | output += f" | ||
+ | output += " | ||
+ | | ||
if args.email: | if args.email: | ||
- | | + | |
- | | + | |
- | email_body = " | + | |
- | send_email(email_subject, | + | |
if __name__ == " | if __name__ == " | ||
main() | main() | ||
+ | |||
</ | </ | ||
python/deezer-album-tracker.1711645438.txt.gz · Last modified: 2024/03/28 17:03 by Wulf Rajek