Archiwa tagu: pulpit

MPD, conky i okładka albumu na pulpicie.

Korzystając z tego, że wersja conky w Ubuntu 10.04 obsługuje wyświetlanie obrazów, postanowiłem zagłębić się w problem wyświetlania okładki słuchanego albumu na pulpicie przez conky.

Szukając na sieci można znaleźć kilka skryptów do ściągania okładek albumów. Niestety jakoś żaden nie wydał mi się atrakcyjny. Postanowiłem sam coś napisać. Jako baza posłużył mi część kodu Sonaty (klienta MPD).

mpd_cover.py

#!/usr/bin/python
#-*- coding: utf-8 -*-
 
import mpdclient2
import urllib
import urllib2
from xml.etree import ElementTree
import threading
import os
import shutil
 
home_dir = os.path.expandvars('$HOME')
m = mpdclient2.connect()
covers_dir = home_dir + '/.covers_conky/'
current_art_alb = covers_dir + 'current'
current_cover = covers_dir + 'current_cover.jpg'
 
def write_current_art_album(artist, album):
	#zapisz aktulany artist album
	file = open(current_art_alb, 'w')
	file.write('%s - %s' % (artist, album))
	file.close()
 
def find_local_artwork(artist, album):
	if os.path.exists(covers_dir + "%s - %s.jpg"):
		return True
	else:
		return False
 
def download_artwork(artist, album, dest_filename, all_images=False):
 
	rhapsody_uri = "http://feeds.rhapsody.com"
	url = "%s/%s/%s/data.xml" % (rhapsody_uri, artist, album)
	url = url.replace(" ", "").replace("'", "").replace("&","")
	request = urllib2.Request(url)
	opener = urllib2.build_opener()
 
	try:
		body = opener.open(request).read()
		xml = ElementTree.fromstring(body)
		imgs = xml.getiterator("img")
	except:
		return False
 
	imglist = [im.attrib['src'] for im in imgs if im.attrib['src']]
	# Couldn't find any images
	if not imglist:
		return False
 
	if not all_images:
		urllib.urlretrieve(imglist[-1], dest_filename)
		return True
 
if m.status()['state'] == 'stop':
	pass
else:
	artist = m.currentsong()['artist']
	album = m.currentsong()['album']
	desc_filename = covers_dir + "%s - %s.jpg" % (artist, album)
 
	if os.path.exists(current_art_alb):
		cur_art_alb = open(current_art_alb, 'r').readline()
		cur_art_alb.strip('\n')
 
		if cur_art_alb == '%s - %s' % (artist, album):
			#ten sam album nic nie rób
			pass
		else:
			#sprawdź czy już istnieje tak okładka
			if find_local_artwork(artist, album):
				#plik już istneje tylko przekopiuj
				shutil.copy(covers_dir + "%s - %s.jpg" % (artist, album), current_cover)
 
				#zapisz aktulany artist album
				write_current_art_album(artist, album)
			else:
				#zapisz aktualny artist album
				write_current_art_album(artist, album)
 
				#ściągnij i przekopiuj
				if download_artwork(artist, album, desc_filename):
					shutil.copy(covers_dir + "%s - %s.jpg" % (artist, album), current_cover)
				else:
					open(current_cover, 'w').write('')
	else:
		#zapisz aktulany artis album
		write_current_art_album(artist, album)
 
		#nie istnieje - ściągnij - przekopuj jako current cover
		if find_local_artwork(artist, album):
			#plik już istneje tylko przekopiuj
			shutil.copy(covers_dir + "%s - %s.jpg" % (artist, album), current_cover)
		else:
			#ściągnij i przekopiuj
			if download_artwork(artist, album, desc_filename):
				shutil.copy(covers_dir + "%s - %s.jpg" % (artist, album), current_cover)
			else:
				open(current_cover, 'w').write('')

Skrypt zapisałem do /usr/local/bin (nadając prawa do uruchamiania). Pamiętajcie o odpowiednich importach dla pythona.
Wykorzystałem dwie instancję conky. Jedna do wyświetlania tylko opisu tego  co jest grane. Druga tylko do wyświetlania okładki album. Chciała uzyskać efekt – opis wyświetlany jest po lewej stronie okładki a samo conky wyświetlane jest w prawym dolnym rogu. Nie znalazłem sposobu na wyświetlenie tego efektu z wykorzystaniem tylko jednej instancji conky, chyba że wykorzystując LUA ale niestety jeszcze nie zgłębiłem tematu.

conkyrc_mpd (wymagany font Engebrechtre)

#opcje

use_xft yes
font Engebrechtre:size=10
override_utf8_locale yes
uppercase no

update_interval 2
music_player_interval 2

text_buffer_size 512

total_run_times 0

background yes
own_window yes
own_window_type override
own_window_transparent yes
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
double_buffer yes

draw_shades no
draw_outline no
draw_borders no
draw_graph_borders no

#minimum_size 300 5

default_color FFFFFF
default_shade_color black
default_outline_color black

alignment bottom_right
gap_x 220
gap_y 65

no_buffers yes

mpd_host localhost

imlib_cache_size 0
#
TEXT
${if_mpd_playing}${font Engebrechtre:size=30}${alignr}${mpd_title}${font}
${font Engebrechtre:size=24}${alignr}${voffset 10}${mpd_artist}${font}
${font Engebrechtre:size=18}${alignr}${voffset 10}${mpd_album}${font}
${font Engebrechtre:size=12}${alignr}${voffset 20}${mpd_status}${font}${endif}

conkyrc_mpd_cover

#opcje 

use_xft yes
font Engebrechtre:size=10
override_utf8_locale yes
uppercase no 

update_interval 2
music_player_interval 2

text_buffer_size 512

total_run_times 0

background yes
own_window yes
own_window_type override
own_window_transparent yes
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
double_buffer yes

draw_shades no
draw_outline no
draw_borders no
draw_graph_borders no

minimum_size 200 200

default_color FFFFFF
default_shade_color black
default_outline_color black

alignment bottom_right
gap_x 10
gap_y 50

no_buffers yes

mpd_host localhost

imlib_cache_size 0
#
TEXT
${if_mpd_playing}
${image /home/daniel/.conky_picture/mpd_conky_back.png -p 1,1 -s 198x198}${image /home/daniel/.covers_conky/current_cover.jpg -p 26,26 -s 150x150}${execpi 10 mpd_cover.py}${endif}

Tworzymy katalog o nazwie .covers_conky, w którym znajdować będą się ściągnięte już okładki oraz aktualna okładka. Katalog .conky_picture z ostatniego pliku konfiguracyjnego przetrzymuje tło dla wyświetlanej okładki.

Następnie uruchamiamy dwie instancje conky podając jako argumenty ścieżki do plików do tych plików konfiguracyjnych (np. conky -c ~/.conkyrc_mpd i conky -c ~/.conkyrc_mpd_cover).

W galerii znajdziecie także tła dla okładek. Przydają się, gdyż może się zdarzyć, że skrypt nie znajdzie okładki album. W takiej sytuacji gadżet wygląda mniej „pusto” :).

Zaktualizowałem skrypt python’a (03.06.2010).

A oto efekt: