2
0
Fork 0

change to aigpy and tidalapi

This commit is contained in:
Luca Bilke 2023-06-26 20:54:02 +02:00
commit 307da06b17
6 changed files with 162 additions and 291 deletions

View file

@ -1,18 +1,111 @@
#!/bin/python3
#!/bin/env python
import tidalapi
import aigpy
import aigpy.downloadHelper
import json
import sys
import base64
from Crypto.Cipher import AES
from Crypto.Util import Counter
from typing import Tuple
from datetime import datetime
USER_ID = 188721652
DL_PATH = "/home/luca/.cache/tidal_scrape"
DEST_PATH = "/home/luca/Music"
config = tidalapi.Config(quality=tidalapi.Quality.lossless)
session = tidalapi.Session(config)
def decrypt_token(token) -> Tuple[bytes, bytes]:
master_key = "UIlTTEMmmLfGowo/UC60x2H45W6MdGgTRfo/umg4754="
master_key = base64.b64decode(master_key)
security_token = base64.b64decode(token)
iv = security_token[:16]
encrypted_st = security_token[16:]
decryptor = AES.new(master_key, AES.MODE_CBC, iv)
decrypted_st = decryptor.decrypt(encrypted_st)
key = decrypted_st[:16]
nonce = decrypted_st[16:24]
return key, nonce
def decrypt_file(input_file, output_file, key, nonce) -> None:
counter = Counter.new(64, prefix=nonce, initial_value=0)
decryptor = AES.new(key, AES.MODE_CTR, counter=counter)
with open(input_file, "rb") as i:
data = decryptor.decrypt(i.read())
with open(output_file, "wb") as o:
o.write(data)
def set_metadata(track: tidalapi.Track, file: str):
# This function could be more fleshed out (lyrics, covers) but I will leave that to external programs
tagger = aigpy.tag.TagTool(file)
tagger.title = track.name
tagger.artist = list(map(lambda artist: artist.name, track.artists)) # type: ignore[reportOptionalMemberAccess]
tagger.copyright = track.copyright
tagger.tracknumber = track.track_num
tagger.discnumber = track.volume_num
tagger.album = track.album.name # type: ignore[reportOptionalMemberAccess]
tagger.albumartist = list(map(lambda artist: artist.name, track.album.artists)) # type: ignore[reportOptionalMemberAccess]
tagger.date = track.album.available_release_date # type: ignore[reportOptionalMemberAccess]
tagger.totaldisc = track.album.num_volumes or 0 # type: ignore[reportOptionalMemberAccess]
if tagger.totaldisc <= 1:
tagger.totaltrack = track.album.num_tracks # type: ignore[reportOptionalMemberAccess]
tagger.save()
def download_track(
track: tidalapi.Track,
partSize: int = 1048576,
) -> Tuple[bool, str]:
try:
dl_path = f"{DL_PATH}/{track.album.name}/{track.name}.part" # type: ignore[reportOptionalMemberAccess]
dest_path = f"{DEST_PATH}/{track.album.name}/{track.name}" # type: ignore[reportOptionalMemberAccess]
stream = track.stream()
stream.manifest = json.loads(base64.b64decode(stream.manifest))
url = stream.manifest["urls"][0]
try:
key = stream.manifest["keyId"]
except KeyError:
key = None
tool = aigpy.downloadHelper.DownloadTool(dl_path, [url])
tool.setPartSize(partSize)
check, err = tool.start(True, 1)
if not check:
return False, str(err)
if key:
key, nonce = decrypt_token(key)
decrypt_file(dl_path, dest_path, key, nonce)
set_metadata(track, dest_path)
return True, ""
except Exception as err:
return False, str(err)
try:
with open("auth.json", "rb") as f:
a = json.load(f)
a.expiry_time = datetime.strptime(a.expiry_time, "%y-%m-%d %H:%M:%S")
expiry_time = a["expiry_time"].split(".", 1)[0]
expiry_time = datetime.strptime(expiry_time, "%Y-%m-%d %H:%M:%S")
session.load_oauth_session(
a.token_type, a.access_token, a.refresh_token, a.expiry_time
a["token_type"], a["access_token"], a["refresh_token"], expiry_time
)
except (OSError, IndexError):
session.login_oauth_simple()
@ -24,22 +117,20 @@ if session.check_login():
"token_type": session.token_type,
"access_token": session.access_token,
"refresh_token": session.refresh_token,
"expiry_time": session.expiry_time,
"expiry_time": str(session.expiry_time),
},
f,
)
else:
sys.exit("Failed to log in")
user = session.get_user()
# albums = user.Favorites.albums()
# tracks = user.Favorites.tracks()
# artists = user.Favorites.artists()
#
# for album in albums:
# if album.artist not in artists:
# user.Favorites.add_artist(album.artist.id)
#
# for track in tracks:
# if track.album not in albums:
# user.Favorites.add_album(track.album.id)
user = session.get_user(USER_ID)
favorites = tidalapi.user.Favorites(session, user.id)
tracks = favorites.tracks()
for track in tracks:
print(f"Downloading {track.album.name} by {track.artist}")
check, err = download_track(track)
if not check:
print(err)