You are not logged in.
Like I said, they're just "papercuts", which is Canonical's term for tiny, relatively insignificant bugs.
First of all, GREAT TURNAROUND!!! I understand that's one of Python's strengths. I assume if I create a symlink to ~/.cache/album_art named .music_art, the script would automatically use the Banshee art? I guess I could just change the path in your script and get the same result. I just mentioned that naming format because that's what I already had, and I'm sure I'm not the only #! user who already has some Banshee art cached.
Regarding the papercuts:
1. Yep, I already had the .noalbum image. I still think that's something external to your script, and therefore not within your control. (Checking for cached art may take care of it though.)
2. I was trying out mpd just now; looks like neither mpd nor moc reports albumartist. Not surprising. As long as the right artist name is scrobbled I'm happy - gotta give these indie artist's their props any way we can, right? 
3. I just mentioned this because it was somewhat evident in Megan's photo in the screenshot I posted. Not a big deal at all.
You totally !..!
EDIT: The script as posted doesn't work with mpd (which I'm using because of the scrobbling support); '"mpd "' should be '"mpd"'. That one space makes all the difference. 
What parts would I change if I wanted it to recognize my existing Banshee art cache, which is named using the format 'artistname-albumname.jpg'? I think I may be on the right track, but I'm not sure. I'll take a whack at it and post my edited script for your feedback.
Last edited by pvsage (2009-11-03 00:23:28)
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Here's how I've tweaked the script:
#!/usr/bin/python
import commands
from optparse import OptionParser
#retrieve track info from player
def get_info():
check_running = commands.getoutput("ps aux")
check_running = check_running.split("\n")
for line in check_running:
if "mocp" in line:
return commands.getoutput("mocp -Q %artist"),commands.getoutput("mocp -Q %album"),commands.getoutput("mocp -Q %song")
if "rhythmbox" in line:
return commands.getoutput("rhythmbox-client --print-playing-format %ta"),commands.getoutput("rhythmbox-client --print-playing-format %at"),commands.getoutput("rhythmbox-client --print-playing-format %tt")
if "xmms2" in line:
info = commands.getoutput("xmms2 info")
for item in info.split("\n"):
if "artist" in item and not "artist_id" in item:
artist = item.split("=")[1].lstrip()
if "album" in item and not "album_id" in item:
album = item.split("=")[1].lstrip()
if "title" in item and not "title_id" in item:
title = item.split("=")[1].lstrip()
return artist, album, title
#if "banshee" in line and not "query" in line:
# return commands.getoutput("banshee --query-artist").split(":").pop(), commands.getoutput("banshee --query-album").split(":").pop(), commands.getoutput("banshee --query-title").split(":").pop()
if "mpd" in line:
try:
import mpdclient2
except:
print "please install python-mpdclient"
raise SystemExit()
mpd = mpdclient2.connect()
song = mpd.currentsong()
if song:
return song.artist, song.album, song.title
else:
return "","",""
return "","",""
#resize image
def size_image(width, height, path):
image = Image.open(path)
image = image.resize((width, height))
image.save(path, "png")
#add reflection to image
def reflect(width, height, path):
image = Image.open(path)
flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
final_image = Image.new('RGBA', (width, (height * 2) + 1) , (0, 0, 0, 0))
gradient = Image.new('L', (1,255))
for y in range(255, 0, -1):
if y < 128:
gradient.putpixel((0,y),255 - (y * 2))
else:
gradient.putpixel((0,255-y),0)
alpha = gradient.resize(flipped_image.size)
flipped_image.putalpha(alpha)
final_image.paste(image, (0, 0))
final_image.paste(flipped_image, (0, height + 1))
final_image.save(path, "png")
def check_album():
if artist == "" and album == "":
if os.path.exists(home + "/.album"):
os.remove(home + "/.album")
if os.path.exists("/tmp/trackinfo"):
os.remove("/tmp/trackinfo")
return False
elif os.path.exists("/tmp/trackinfo") and open("/tmp/trackinfo").read() == artist + album:
return False
return True
#fetch album
def get_album():
if not os.path.exists(home + "/.cache/album-art/"):
commands.getoutput("mkdir %s%s" % (home, "/.cache/album-art/"))
if not os.path.exists("%s/.cache/album-art/%s-%s.jpg" % (home, artist, album)):
api_album = api.get_album(album, artist)
if api_album.image["extralarge"]:
urllib.urlretrieve(api_album.image["extralarge"], "%s/.cache/album-art/%s-%s.jpg" % (home, artist, album))
elif api_album.image["large"]:
urllib.urlretrieve(api_album.image["large"], "%s/.cache/album-art/%s-%s.jpg" % (home, artist, album))
elif api_album.image["medium"]:
urllib.urlretrieve(api_album.image["medium"], "%s/.cache/album-art/%s-%s.jpg" % (home, artist, album))
elif api_album.image["small"]:
urllib.urlretrieve(api_album.image["small"], "%s/.cache/album-art/%s-%s.jpg" % (home, artist, album))
else:
commands.getoutput("cp %s %s" % (home + "/.noalbum", home + "/.cache/album-art/" + artist + "-" + album + ".jpg"))
open("/tmp/trackinfo","w").write(artist + album)
commands.getoutput("cp '%s' '%s'" % ("%s/.cache/album-art/%s-%s.jpg" % (home, artist, album), home + "/.album"))
size_image(width, height, home + album_path)
if options.reflect:
reflect(width, height, home + album_path)
def check_artist_art():
if artist == "":
if os.path.exists(home + "/.artist"):
os.remove(home + "/.artist")
if os.path.exists("/tmp/artistinfo"):
os.remove("/tmp/artistinfo")
return False
elif os.path.exists("/tmp/artistinfo") and open("/tmp/artistinfo").read() == artist:
return False
return True
#fetch artist art
def get_artist_art():
if not os.path.exists(home + "/.cache/album-art/"):
commands.getoutput("mkdir %s%s" % (home, "/.cache/album-art/"))
if not os.path.exists("%s/.cache/album-art/%s.jpg" % (home, artist)):
api_artist = api.get_artist(artist)
if api_artist.image["extralarge"]:
urllib.urlretrieve(api_artist.image["extralarge"], home + "/.cache/album-art/" + artist + ".jpg")
elif api_artist.image["large"]:
urllib.urlretrieve(api_artist.image["large"], home + "/.cache/album-art/" + artist + ".jpg")
elif api_artist.image["medium"]:
urllib.urlretrieve(api_artist.image["medium"], home + "/.cache/album-art/" + artist + ".jpg")
elif api_artist.image["small"]:
urllib.urlretrieve(api_artist.image["small"], home + "/.cache/album-art/" + artist + ".jpg")
else:
commands.getoutput("cp %s %s" % (home + "/.noalbum", home + "/.cache/album-art/" + artist + ".jpg"))
open("/tmp/artistinfo","w").write(artist)
commands.getoutput("cp '%s' '%s'" % ("%s/.cache/album-art/%s.jpg" % (home, artist), home + "/.artist"))
size_image(width, height, home + artist_path)
if options.reflect:
reflect(width, height, home + artist_path)
def check_similar():
if title == "":
if os.path.exists(home + "/.similar"):
os.remove(home + "/.similar")
if os.path.exists("/tmp/titleinfo"):
os.remove("/tmp/titleinfo")
return False
if os.path.exists("/tmp/titleinfo") and open("/tmp/titleinfo").read() == title:
return False
return True
def get_similar():
api_artist = api.get_artist(artist)
out = ""
for item in api_artist.get_similar(limit=5):
out = out + item.name + "\n"
open(home + "/.similar", "w").write(out)
#set up command line options
parser = OptionParser()
parser.add_option("-s", "--size", dest="size", default="80x80", help="image size")
parser.add_option("-r", "--reflect", action="store_true", dest="reflect", default=False, help="image reflection")
parser.add_option("-a", "--artist-art", action="store_true", dest="artist_art", default=False, help="artist image")
parser.add_option("--artist", action="store_true", dest="return_artist", default=False, help="artist")
parser.add_option("--album", action="store_true", dest="return_album", default=False, help="album")
parser.add_option("--title", action="store_true", dest="return_title", default=False, help="title")
parser.add_option("--similar", action="store_true", dest="similar_artists", default=False, help="similar artists")
(options, args) = parser.parse_args()
#check if size is valid
try:
width,height = options.size.split("x")
width = int(width)
height = int(height)
except:
parser.error("please specify size in WIDTHxHEIGHT format")
artist, album, title = get_info()
#return artis, album, or title
if options.return_artist:
print artist
raise SystemExit()
if options.return_album:
print album
raise SystemExit()
if options.return_title:
print title
raise SystemExit()
import Image, os
#set up variables
home = os.getenv("HOME")
album_path = "/.album"
artist_path = "/.artist"
api_key = "b25b959554ed76058ac220b7b2e0a026"
if check_artist_art() or check_album() or check_similar():
import urllib, lastfm
api = lastfm.Api(api_key)
if options.similar_artists and check_similar():
get_similar()
if os.path.exists(home + "/.similar"):
print open(home + "/.similar").read()
raise SystemExit()
if options.artist_art and check_artist_art():
get_artist_art()
if check_album():
get_album()Does that look right? The only thing I'm not certain about is the %s.jpg part; I'm not sure if that will get parsed properly.
EDIT: OK, I didn't realize we hadn't already included the remove whitespace and convert to lowercase part. I'll look that up and try to implement it on my own. (Time to leapfrog way past "Hello World"!)
Last edited by pvsage (2009-11-03 00:47:46)
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
seems ok to me if your unsure whether a string is getting handled properly just run the script in the terminal and print out the string when it gets to that point
- - - - - - - - Wiki Pages - - - - - - -
#! install guide *autostart programs, modify the menu & keybindings
configuring Conky *installing scripts
Offline
It looks like it's working right.
Although getting it from here to where it exactly matches Banshee's cached images is probably just a couple joins and a few regex's away, it probably doesn't make much sense to do so since the smaller images appear to be good for most users. The bigger images sure are purty, but they take up a lot more space on disk.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Good idea benj1 on the symlinking, I had it copy before because it wasn't caching so had to redownload each time. That should speed it up a little. If you want to patch it I'd appreciate it, I don't usually use mpd... I only installed it so I could add support in the script. I've just picked up python from tutorials so any help I can get on better ways to do things is always appreciated. 
edit: if you'd prefer the names lowercased and stripped of whitespace it should be pretty easy, I'm at work now though so it'll have to wait untill I get home.
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
^ Consider that a homework assignment for me. I like it the way it is now (actually...no, nevermind); in fact, I don't understand whybansheedoesthealllowercaseandstrippedofwhatsnota-z0-9.
I understand why they'd replace unicode characters though.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
well it does make some sense, if your collection isn't entirely up to snuff(as is mine). If you have the album "Whatever" and the same album "whatever" it would have two images using my script...so it would make sense to normalize the album and artist names. Plus it gets rid of issues with whitespace in the script(which is why my copy command has the '%s' instead of just %s)
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
Hi iggykoopa,
It' really looks amazing what you have done. I have just browsed this thread and I am wondering if your detailed install instructions on page 2 is still valid? It would be really nice to have an absolutely cool desktop almost 'plug'n'play' like.
Anyways - cheers!
Offline
I'm pretty sure the only thing missing from the instructions is a dependancy I had missed... you'll need to install python-decorator as well(it's in the normal repos). If you have any other issues let me know and I can walk you through it.
edit: also grab the most recent version of the script...it's a couple posts up, keep checking back though as I'll probably make a few changes tonight if I have time.
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
Good idea benj1 on the symlinking, I had it copy before because it wasn't caching so had to redownload each time. That should speed it up a little. If you want to patch it I'd appreciate it, I don't usually use mpd... I only installed it so I could add support in the script. I've just picked up python from tutorials so any help I can get on better ways to do things is always appreciated.
me too 
anyway ive updated the script to search for python-mpd
ive posted it here http://crunchbanglinux.org/pastebin/379
i havent changed anything else.
is it just this line/only line that would need to be modified for symlinking, i wasnt sure.
commands.getoutput("cp '%s' '%s'" % ("%s/.music_art/%s" % (home, artist), home + "/.artist"))to
os.symlink("%s/.music_art/%s" % (home, artist),home + "/.artist" )- - - - - - - - Wiki Pages - - - - - - -
#! install guide *autostart programs, modify the menu & keybindings
configuring Conky *installing scripts
Offline
that line and the one for album art.
commands.getoutput("cp '%s' '%s'" % ("%s/.music_art/%s-%s" % (home, artist, album), home + "/.album"))to
os.symlink("%s/.music_art/%s-%s" % (home, artist, album) ,home + "/.album" )I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
right done that
http://crunchbanglinux.org/pastebin/380
- - - - - - - - Wiki Pages - - - - - - -
#! install guide *autostart programs, modify the menu & keybindings
configuring Conky *installing scripts
Offline
well it does make some sense, if your collection isn't entirely up to snuff(as is mine).
Oh snap!
Some of my titles just don't lend themselves well to grabbing the right art. One particular example? The Planets suite by Gustav Holst, recorded by André Previn and the Royal Philharmonic. I get around these using the cacheing script by downloading the art from Amazon and renaming it according to how the script interprets the artist and album tags. 
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Oh I was saying mine wasn't up to snuff either. Once you get around 60 gigs of music it's just not worth the effort to try to fix everything.
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
I think mine would be close to 60GB if it had all been ripped as FLAC; most of it was ripped as 128kbps mp3 on a Windowsbox years ago, then the CD's sold to make rent. 
Last edited by pvsage (2009-11-03 14:56:57)
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Resizing an image in Python while maintaining aspect ratio:
http://www.modscape.com/2008/09/04/resi … io-python/
...but I can't for the life of me seem to get it working within iggykoopa's script.
I think the easiest way (from an end-user perspective) would be to include one fragment to match width and another to match height, and let the user uncomment the one that suits his aesthetic needs.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
OK, I got it to match width anyway; if I try to match height with an image that's taller than it is wide, both images are scaled larger than the values defined in the arguments passed by Conky. It's just a few tweaks away though!
Here are the changes:
import PIL
from PIL import Image
#resize image
def size_image(width, height, path):
image = Image.open(path)
wpercent = (height/float(image.size[0]))
hsize = int((float(image.size[1])*float(wpercent)))
image = image.resize((width,hsize), PIL.Image.ANTIALIAS)
image.save(path, "png")...and here's an example of the output with an image that's wider than it is tall:
Note that the change includes using the PIL anti-alias filter; this really improves the image quality.
EDIT: I have screen grabs of low-res album art scaled to 400x400 - one with anti-aliasing, one without - if anyone needs to see how much difference it makes.
Last edited by pvsage (2009-11-05 04:18:01)
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
great job. sorry I haven't been working on this lately, they extended my work day so I don't have much free time. It looks like your having fun learning though so feel free to run with it 
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
Well, this morning I'm not getting images or similar at all. Maybe the LastFM API server is down? Last night it had trouble getting similar artists for well-established bands like Three Dog Night and The B-52's.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Is anyone else not getting anything from the LastFM API lately? I even went and got my own API key and it still doesn't work.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
it's just you I think...I just tested with an album I hadn't played before and it got the images.
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
Is anyone else not getting anything from the LastFM API lately? I even went and got my own API key and it still doesn't work.
if your still having problems and feel like a project, my album art script linked in the mpd thread uses amazon to get artwork, you could port that over 
- - - - - - - - Wiki Pages - - - - - - -
#! install guide *autostart programs, modify the menu & keybindings
configuring Conky *installing scripts
Offline
^ Thanks, I think Amazon's art tends to be higher res? But I really miss my "similar artists", so I'll try to get my LastFM unborked.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
you could always combine the two, pull art from amazon and similar artist's from last.fm. I just settled with last.fm because the api is pretty nice and it's easy to work with.
I say never be complete, I say stop being perfect, I say lets evolve, let the chips fall where they may.
Offline
I still haven't figured out how I borked things; a fresh install and rebuild and I'm laughing again. I must have installed or uninstalled something that caused a conflict.
while ( ! ( succeed = try() ) );
We've earned a reputation as a nice, friendly community; please help us keep it that way.
Online
Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.