wmt.py (4422B)
1 #!/usr/bin/env python 2 """ 3 ██ 4 ░██ 5 ███ ██ ██████████ ██████ 6 ░░██ █ ░██░░██░░██░░██░░░██░ 7 ░██ ███░██ ░██ ░██ ░██ ░██ 8 ░████░████ ░██ ░██ ░██ ░██ 9 ███░ ░░░██ ███ ░██ ░██ ░░██ 10 ░░░ ░░░ ░░░ ░░ ░░ ░░ 11 w e e k l y m u s i c t o o t 12 13 author ▓▒ pyratebeard <root@pyratebeard.net> 14 code ▓▒ https://git.pyratebeard.net/wmt 15 16 `wmt` is used for sending an automated toot 17 to my mastodon profile listing the music that 18 has been listened to on my navidrome server 19 since the previous monday. 20 21 it is an advancement of my wmt script used 22 with cmus. since i am on the move a bit more 23 i don't use cmus all the time. i also wanted 24 to include music that i listen to outside of 25 work. 26 27 the main difference is the cmus script put 28 the list into most to least played. this one 29 does not, yet. i would like to combine the 30 two lists if possible but for now this will 31 be the list posted to mastodon. 32 """ 33 34 import requests 35 import os 36 import datetime 37 from dotenv import load_dotenv, dotenv_values 38 from subprocess import check_output 39 from mastodon import Mastodon 40 41 # pull vars and secrets from .env file 42 # if the file does not exist write the 43 # required vars to a new file and exit 44 cwd = os.path.dirname(os.path.realpath(__file__)) 45 var_file = cwd + '/.env' 46 local_vars = ['NAVIDROME_URL', # instance url 47 'USERNAME', # navidrome username 48 'PASSWORD', # navidrome password 49 'ALBUM_LIMIT', # request result album limit, default 20 50 'NTFY_URL', # instance and tag url 51 'MASTODON_URL', # instance url 52 'ACCESS_TOKEN'] # app access token 53 54 if not os.path.exists(var_file): 55 # add `=""` to each var to make it as 56 # easy as possible to populate 57 content = '=""\n'.join(local_vars) + '=""\n' 58 with open(var_file, "x", encoding="utf-8") as f: 59 f.writelines(content) 60 print(f"local var file {var_file} created\npopulate and run again") 61 exit() 62 else: 63 load_dotenv() 64 65 # log in to navidrome instance 66 NAVIDROME_URL = os.getenv('NAVIDROME_URL') 67 login_url = f'{NAVIDROME_URL}/auth/login' 68 login_data = { 69 'username': os.getenv("USERNAME"), 70 'password': os.getenv("PASSWORD") 71 } 72 73 try: 74 login_res = requests.post(login_url, json=login_data) 75 login_res.raise_for_status() 76 token = login_res.json().get('token') 77 if not token: 78 print("login succeeded but no token received.") 79 exit() 80 except Exception as e: 81 print(f"login failed: {e}") 82 exit() 83 84 headers = { 85 'X-ND-Authorization': f'Bearer {token}' 86 } 87 88 # set data and pull album list 89 params = { 90 '_start': 0, 91 '_end': os.getenv("ALBUM_LIMIT", 20), 92 '_sort': 'play_date', 93 '_order': 'DESC', 94 'recently_played': 'true' 95 } 96 97 try: 98 res = requests.get(f'{NAVIDROME_URL}/api/album', headers=headers, params=params) 99 res.raise_for_status() 100 albums = res.json() 101 except Exception as e: 102 print(f"failed to fetch albums: {e}") 103 exit() 104 105 # get last monday date to start new week 106 today = datetime.date.today() 107 monday = today - datetime.timedelta(days=today.weekday()) 108 109 # find all albums played since monday 110 week_music = [] 111 for a in albums: 112 play_date = datetime.datetime.fromisoformat(a.get('playDate')) 113 if play_date.date() >= monday: 114 week_music.append(f"{a['name']} by {a['artist']}") 115 116 # compose toot 117 toot = (f"""(automated) #weeklymusictoot 118 119 this week i listened to: 120 121 """) 122 123 # 500 char max 124 # toot is 54 chars inc newlines 125 # albums no more than 446 so slice 126 # last album until list fits 127 while True: 128 char_count = sum(len(s) for s in week_music) 129 if char_count > 446: 130 week_music = week_music[:-1] 131 else: 132 break 133 134 # add albums to toot 135 for album in week_music: 136 toot += f"* {album}\n" 137 138 # post toot 139 try: 140 MASTODON_URL = os.getenv("MASTODON_URL") 141 ACCESS_TOKEN = os.getenv("ACCESS_TOKEN") 142 mastodon = Mastodon(api_base_url = MASTODON_URL, access_token = ACCESS_TOKEN) 143 mastodon.toot(toot) 144 except Exception as e: 145 NTFY_URL = os.getenv("NTFY_URL") 146 requests.post(NTFY_URL, 147 data="wmt toot failed".encode(encoding='utf-8')) 148 exit()