Skip to content

Instantly share code, notes, and snippets.

@aqua-lzma
Last active August 23, 2021 15:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aqua-lzma/999285ec3fcf3c7ac095a1cf65c24066 to your computer and use it in GitHub Desktop.
Save aqua-lzma/999285ec3fcf3c7ac095a1cf65c24066 to your computer and use it in GitHub Desktop.
Generate a collage of every album cover ever listened to on last.fm
import json, sys, math
from io import BytesIO
import requests
from PIL import Image
username = ""
apikey = ""
url = (
"http://ws.audioscrobbler.com/2.0/"
"?method=user.getTopAlbums"
"&format=json"
"&limit"
"&user={user}"
"&api_key={apikey}"
"&page={page}"
"&limit=100"
"&period=overall"
)
page = 1
totalPages = 1
albumImages = []
while page < totalPages + 1:
req = requests.get(url.format(user=username, apikey=apikey, page=page)).text
jreq = json.loads(req)
print("---------- Page {:02} ----------".format(page))
for album in jreq["topalbums"]["album"]:
print("{} / {} - {}".format(album["@attr"]["rank"].rjust(len(jreq["topalbums"]["@attr"]["total"])), jreq["topalbums"]["@attr"]["total"], album["name"]))
for image in album["image"]:
if image["size"] == "large":
if image["#text"] == "":
print("No image, skipping")
else:
albumImages.append(image["#text"])
break
totalPages = int(jreq["topalbums"]["@attr"]["totalPages"])
page += 1
n = len(albumImages)
print("{} album covers fetched".format(n))
cn = math.ceil(math.sqrt(n))
split = -1
for i in range(cn, 1, -1):
if n / i == int(n / i):
split = i
break
width = 0
height = 0
if split == -1:
width = cn
height = math.ceil(n / cn)
else:
print("Use calculated resolution: {}\nIf not, square resolution with blanks: {}".format("{} x {}".format(int(n / split), split), "{} x {}".format(cn, cn)))
if input("y/n :>").lower() == "y":
width = int(n / split)
height = split
else:
width = cn
height = math.ceil(n / cn)
log = "{" + ":0{}".format(len(str(n))) + "}" + " / {}".format(n)
canvas = Image.new("RGBA", (174 * width, 174 * height))
for index, album in enumerate(albumImages):
try:
print(log.format(index), album)
req = requests.get(album)
img = Image.open(BytesIO(req.content))
canvas.paste(img, ((index % width) * 174, (index // width) * 174))
except:
print("Error downloading / pasting image")
continue
print("Saving . . .")
canvas.save("{}.png".format(username))
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment