by fizzjob » Mon Nov 30, 2009 12:33 pm
When I was running this, I noticed it failed on anything that ended in a trailing "The". I modified the code a bit (my first attempt at digging into Python), and it seems to work. I set it to work with a structure of StartDir/Artist/Album, which is different from how lf0 has it.
Code: Select all
#!/usr/bin/python
# Very basic python script to fetch artist images from last.fm
# - You need PIL from http://www.pythonware.com/products/pil
# - You need pylast from http://code.google.com/p/pylast/
# or just http://pylast.googlecode.com/svn/trunk/pylast.py
from httplib import InvalidURL
from os import listdir
from os import path
from os import stat
from stat import ST_MODE
from stat import S_ISDIR
from sys import stdout, version_info
from urllib2 import HTTPError
from urllib2 import Request
from urllib2 import URLError
from urllib2 import urlopen
from ImageFile import Parser
from PIL import Image
from pylast import Artist
from pylast import get_lastfm_network
# basic tweaks
START_DIR = "." # Directory to start scanning
USE_GENRE = False # When True look for START_DIR/Genre/Artist otherwise just use START_DIR/Artist
WRITE_DIRECTORY_ENTRY = False # Write extra PNG file and create .directory file
JPG_FILENAME = "artist.jpg"
PNG_FILENAME = "artist.png"
# You have to have your own unique two values for API_KEY and API_SECRET
# Obtain yours from http://www.last.fm/api/account for Last.fm
API_KEY = "1caaaecb5f85df41359680c0b95191af" # this is a sample key
API_SECRET = "c3f6a6e65a796e813b6c9a2c91e85d79"
def fetch_image(url):
"""
Retrieve a image given by the url.
"""
tries = 0
if not url.startswith('http://'):
return None
while True:
try:
request = Request(url)
reply = urlopen(request)
p = Parser()
while 1:
s = reply.read(1024)
if not s:
break
p.feed(s)
im = p.close()
return im
except (URLError, HTTPError, InvalidURL), e:
tries += 1
if tries >= 3:
print 'error while fetching: %s (%s)' % (url, e)
return None
finally:
if 'reply' in locals():
reply.close()
def get_image(artistName):
artist = Artist(artistName, get_lastfm_network(API_KEY, API_SECRET))
image_list = artist.get_images(limit=1)
if version_info[1] >= 6 and version_info[0] < 3:
url = image_list[0].sizes.original
else:
url = image_list[0]["sizes"]["original"]
return fetch_image(url)
def write_directory(dir):
file = open(path.join(dir, ".directory"), "w")
file.write("[Desktop Entry]\n")
file.write("Icon=./%s\n" % PNG_FILENAME)
file.close()
def save_image(prefix, artistName, size=500):
if artistName.endswith(", The"):
idx = artistName.find(", The")
artistName2 = "The " + artistName[0:idx]
else:
artistName2 = artistName
print "%s.." % artistName2,
directory = path.join(prefix, artistName)
jpgFile = path.join(directory, JPG_FILENAME)
pngFile = path.join(directory, PNG_FILENAME)
if path.exists(jpgFile) or (WRITE_DIRECTORY_ENTRY and path.exists(pngFile)):
print "image exists"
return
stdout.flush()
try:
image = get_image(artistName2)
(w, h) = image.size
# crop only the center of the image
if (w > h):
result = image.crop(((w-h) / 2, 0, (w + h) / 2, h))
else:
result = image.crop((0, (h-w) / 2, w, (w + h) / 2))
if result.mode != "RGB":
result = result.convert("RGB")
result = result.resize((size, size), Image.BICUBIC)
result.save(jpgFile, "JPEG")
if WRITE_DIRECTORY_ENTRY:
result.save(pngFile, "PNG")
write_directory(directory)
print "ok"
except (IOError), e:
print "could not save image"
print e
except (Exception), e:
print "could not convert image"
print e
def walk_artists(dir):
dirList = listdir(dir)
for artistName in dirList:
artistDir = path.join(dir, artistName)
mode = stat(artistDir)[ST_MODE]
if S_ISDIR(mode):
save_image(dir, artistName.decode('utf-8'))
def walk_genres(dir):
dirList = listdir(dir)
for genreName in dirList:
genreDir = path.join(dir, genreName)
mode = stat(genreName)[ST_MODE]
if S_ISDIR(mode):
walk_artists(genreDir)
if __name__ == "__main__":
if USE_GENRE:
walk_genres(START_DIR)
else:
walk_artists(START_DIR)
When I was running this, I noticed it failed on anything that ended in a trailing "The". I modified the code a bit (my first attempt at digging into Python), and it seems to work. I set it to work with a structure of StartDir/Artist/Album, which is different from how lf0 has it.
[code]#!/usr/bin/python
# Very basic python script to fetch artist images from last.fm
# - You need PIL from http://www.pythonware.com/products/pil
# - You need pylast from http://code.google.com/p/pylast/
# or just http://pylast.googlecode.com/svn/trunk/pylast.py
from httplib import InvalidURL
from os import listdir
from os import path
from os import stat
from stat import ST_MODE
from stat import S_ISDIR
from sys import stdout, version_info
from urllib2 import HTTPError
from urllib2 import Request
from urllib2 import URLError
from urllib2 import urlopen
from ImageFile import Parser
from PIL import Image
from pylast import Artist
from pylast import get_lastfm_network
# basic tweaks
START_DIR = "." # Directory to start scanning
USE_GENRE = False # When True look for START_DIR/Genre/Artist otherwise just use START_DIR/Artist
WRITE_DIRECTORY_ENTRY = False # Write extra PNG file and create .directory file
JPG_FILENAME = "artist.jpg"
PNG_FILENAME = "artist.png"
# You have to have your own unique two values for API_KEY and API_SECRET
# Obtain yours from http://www.last.fm/api/account for Last.fm
API_KEY = "1caaaecb5f85df41359680c0b95191af" # this is a sample key
API_SECRET = "c3f6a6e65a796e813b6c9a2c91e85d79"
def fetch_image(url):
"""
Retrieve a image given by the url.
"""
tries = 0
if not url.startswith('http://'):
return None
while True:
try:
request = Request(url)
reply = urlopen(request)
p = Parser()
while 1:
s = reply.read(1024)
if not s:
break
p.feed(s)
im = p.close()
return im
except (URLError, HTTPError, InvalidURL), e:
tries += 1
if tries >= 3:
print 'error while fetching: %s (%s)' % (url, e)
return None
finally:
if 'reply' in locals():
reply.close()
def get_image(artistName):
artist = Artist(artistName, get_lastfm_network(API_KEY, API_SECRET))
image_list = artist.get_images(limit=1)
if version_info[1] >= 6 and version_info[0] < 3:
url = image_list[0].sizes.original
else:
url = image_list[0]["sizes"]["original"]
return fetch_image(url)
def write_directory(dir):
file = open(path.join(dir, ".directory"), "w")
file.write("[Desktop Entry]\n")
file.write("Icon=./%s\n" % PNG_FILENAME)
file.close()
def save_image(prefix, artistName, size=500):
if artistName.endswith(", The"):
idx = artistName.find(", The")
artistName2 = "The " + artistName[0:idx]
else:
artistName2 = artistName
print "%s.." % artistName2,
directory = path.join(prefix, artistName)
jpgFile = path.join(directory, JPG_FILENAME)
pngFile = path.join(directory, PNG_FILENAME)
if path.exists(jpgFile) or (WRITE_DIRECTORY_ENTRY and path.exists(pngFile)):
print "image exists"
return
stdout.flush()
try:
image = get_image(artistName2)
(w, h) = image.size
# crop only the center of the image
if (w > h):
result = image.crop(((w-h) / 2, 0, (w + h) / 2, h))
else:
result = image.crop((0, (h-w) / 2, w, (w + h) / 2))
if result.mode != "RGB":
result = result.convert("RGB")
result = result.resize((size, size), Image.BICUBIC)
result.save(jpgFile, "JPEG")
if WRITE_DIRECTORY_ENTRY:
result.save(pngFile, "PNG")
write_directory(directory)
print "ok"
except (IOError), e:
print "could not save image"
print e
except (Exception), e:
print "could not convert image"
print e
def walk_artists(dir):
dirList = listdir(dir)
for artistName in dirList:
artistDir = path.join(dir, artistName)
mode = stat(artistDir)[ST_MODE]
if S_ISDIR(mode):
save_image(dir, artistName.decode('utf-8'))
def walk_genres(dir):
dirList = listdir(dir)
for genreName in dirList:
genreDir = path.join(dir, genreName)
mode = stat(genreName)[ST_MODE]
if S_ISDIR(mode):
walk_artists(genreDir)
if __name__ == "__main__":
if USE_GENRE:
walk_genres(START_DIR)
else:
walk_artists(START_DIR)[/code]