Skip to content

Instantly share code, notes, and snippets.

@Tokariew
Last active February 19, 2020 18:50
Show Gist options
  • Save Tokariew/f7df17789e0d2c341ae42b97e4d866f2 to your computer and use it in GitHub Desktop.
Save Tokariew/f7df17789e0d2c341ae42b97e4d866f2 to your computer and use it in GitHub Desktop.
Download flac tracks from jamendo.com based on artist or album url
import argparse
import json
import re
import time
from concurrent.futures import ThreadPoolExecutor
from itertools import repeat
from pathlib import Path
import requests
from clint.textui import progress
from mutagen import id3
from mutagen.flac import FLAC, Picture
CLIENT_ID = ''
BASEURL = 'http://api.jamendo.com/v3.0/{}/{}/?client_id={}&format=json&limit=1&id={}'
# todo Add ability to download singles
def restring(string):
s = re.sub('[\\/*?:"<>|\']', '_', string)
return re.sub('( |[.])+([.]| )+$', '', s)
def edit_metadata(file_name, track_name, album, artist, releasedate, pos, img):
f = FLAC(file_name)
f['artist'] = artist
f['title'] = track_name
f['album'] = album
f['date'] = releasedate
f['tracknumber'] = pos
f.add_picture(img)
f.save()
time.sleep(.1)
def download(url, file_name):
r = requests.get(url, stream=True)
with open(file_name, 'wb') as f:
total_length = int(r.headers.get('content-length'))
for chunk in progress.bar(r.iter_content(chunk_size=1024),
expected_size=(total_length / 1024) + 1):
if chunk:
f.write(chunk)
f.flush()
def artist_info(id):
url = BASEURL.format('artists', 'albums', CLIENT_ID, id)
r = requests.get(url)
if r.status_code != 200:
return ''
res = json.loads(r.content)['results'][0]
id_list = [item['id'] for item in res['albums']]
for id in id_list:
album_info(id)
def make_img(imgurl):
r = requests.get(imgurl)
img = Picture()
img.data = r.content
img.type = id3.PictureType.COVER_FRONT
img.width = 600
img.height = 600
img.depth = 16
return img
def album_info(id):
url = BASEURL.format('albums', 'tracks', CLIENT_ID,
id) + '&imagesize=600&audioformat=flac'
r = requests.get(url)
if r.status_code != 200:
return ''
res = json.loads(r.content)['results'][0]
imgurl = res['image']
artist = res['artist_name']
album = res['name']
releasedate = res['releasedate']
path = Path(restring(artist)) / Path(f'{releasedate} - {restring(album)}')
path.mkdir(parents=True, exist_ok=True)
print(path)
img = make_img(imgurl)
if 'jpg' in imgurl:
img.mime = u'image/jpeg'
else:
img.mime = u'image/png'
items = [item for item in res['tracks']]
with ThreadPoolExecutor(max_workers=None) as executor:
for track in executor.map(
track_download, items,
repeat((img, path, artist, album, releasedate))):
pass
def track_download(track, *args):
args = args[0]
track_name = track['name']
pos = track['position']
tr = args[1] / Path(f'{int(pos):02d}. {restring(track_name)}.flac')
download(track['audiodownload'], tr)
edit_metadata(tr, track_name, args[3], args[2], args[4], pos, args[0])
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=
'Download albums from jamendo.com based on link in text file')
parser.add_argument('filepaths',
metavar='paths',
type=str,
nargs='+',
help='text files to with links to parse')
file_list = parser.parse_args().filepaths
for file in file_list:
with open(file, mode='r') as f:
for line in f:
id = max(re.findall("[0-9]+", line), key=len)
if 'artist' in line:
artist_info(id)
elif 'album' in line:
album_info(id)
else:
print(f'Not correct url: {line}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment