31 gen 2009

Errore Google


Interessante! Ora però sembra abbiano sistemato!

27 gen 2009

Last.fm API e Python

Il mio primo programma Python non è certamente un esempio da inserire in un manuale di stile, ma non era nemmeno quella l'intenzione; ci tenevo a scrivere qualcosa che fosse utile e che avesse risultati pratici fin da subito.
Con piccole variazioni al codice ho potuto individuare i brani doppi, ho potuto correggere alcuni titoli errati, ho potuto individuare gli artisti che comparivano "sdoppiati" a causa del tag artistsortorder mancante.
Ed ora, che cosa resta?
Ho pensato che sarebbe stato interessante sistemare anche il genere musicale...

Last.fm

Last.fm è un social network di utenti accomunati dalla passione per la musica. Una caratteristica che lo rende interessante è la funzione di scrobbling: di ogni utente viene creato un profilo dettagliato che comprende tutti i brani ascoltati tramite l'apposita radio oppure tramite un plugin installato nel proprio player.
Gli utenti inoltre possono aggiungere dei "tag", ovvero delle etichette, agli artisti, agli album, alle canzoni che ascoltano. Da questi tag è possibile ottenere molte informazioni, tra cui il genere musicale di un artista. Ma come si possono estrarre queste informazioni?

Last.fm API

Fortunatamente Last.fm mette a disposizione dei Web Services attraverso i quali è possibile estrarre tutte le informazioni presenti sul sito. Dato per scontato che non è sempre precisa (il "tag" è un'etichetta generica, che non sempre coincide col genere musicale), la funzione artist.getTopOfTags sembra proprio avvicinarsi il più possibile a quanto stavo cercando.

Il codice

import sys
import win32com.client
import httplib
import urllib
import xml.dom.minidom

dic = dict()

def artistGetTopOfTags(artista):
  artist_url = u"http://ws.audioscrobbler.com/2.0/?method=artist.gettoptags&artist=%s&api_key=b25b959554ed76058ac220b7b2e0a026"
  url = artist_url % urllib.quote(artista.encode('utf8'))
  dom=xml.dom.minidom.parse(urllib.urlopen(url))
  genre=""
  for tag in dom.getElementsByTagName('tag'):
    name = ""
    count = ""
    for child in tag.childNodes:
      if child.nodeName == "name":
        name = child.firstChild.nodeValue
      if child.nodeName == "count":
     count = child.firstChild.nodeValue
    if count=="100":
      genre = name
  return genre.title()

def genere(artista):
  if not artista in dic:
    dic[artista]=artistGetTopOfTags(artista)
    print artista
  return dic[artista]

def main(*args):
  itunes = win32com.client.Dispatch("iTunes.Application")
  mainLibrary = itunes.LibraryPlaylist
  tracks = mainLibrary.Tracks
  numTracks = tracks.Count
  n = 1;

  while n <= numTracks:
    currTrack = tracks.Item(n)
    if genere(currTrack.Artist) != "":
      try:
        currTrack.Genre = genere(currTrack.Artist)
      except:
        print "eccezione!"
    n+=1

if __name__ == '__main__':
  sys.exit(main(*sys.argv))
va bene, le eccezioni dovranno essere gestite meglio, e va bene, il genere musicale non è sempre corretto. Però i portali Web che mettono a disposizione delle funzioni tramite Web Services sono sempre più numerosi (es. Google, Yahoo Weather, etc...) e mi pareva interessante porre le basi per iniziare ad utilizzarli. Sembra che il metodo più pythoniano di parserizzare un file XML consiste nell'utilizzare la libreria ElemenTree, e non la libreria DOM standard... bene vedremo di approfondire anche questo!

21 gen 2009

Aggiornare la libreria di iTunes con Python

Visto che la mia libreria di iTunes non ne voleva sapere di aggiornarsi correttamente, nemmeno utilizzando il buon iTunes Library Updater, ho pensato di approfittare di questo piccolo ma fastidioso inconveniente per iniziare a conoscere - finalmente - il linguaggio di programmazione Python.

Prerequisito 1 - Python!

Quale distribuzione di Python utilizzare? Poiché l'ambiente ActiveState Perl mi è molto familiare, mi sembrava naturale utilizzare ActiveState Python, ma ho notato che gli sviluppatori di Google, nel canale Google Code, preferiscono utilizzare la versione ufficiale tratta dal sito www.python.org e allora... non so ancora perché, non so se e quando lo scoprirò, ma ho deciso di iniziare anch'io con questa versione: migliaia di sviluppatori Google non possono sbagliare!

Prerequisito 2 - Apple SDK

iTunes per Windows è controllabile tramite interfaccia COM: sul sito della Apple è gentilmente messo a disposizione il software developer kit con la documentazione per l'interfaccia COM di iTunes.

Prerequisito 3 - libreria tagging MP3

Dopo anni di programmazione in Perl, sono giunto alla conclusione che le mie prime impressioni erano fin troppo vere: si tratta di un linguaggio brutto, sporco e cattivo. Ciò che lo rende comodo, ma non solo comodo, oserei dire quasi meraviglioso, è la sterminata libreria di moduli, generalmente di ottima qualità, progettati da progettisti degni di tale nome, che risolvono praticamente tutti i problemi della terra.
E per Python, esiste qualcosa di analogo?
Non lo so ancora, e quindi vai con google: il modulo Mutagen sembra proprio quello che stavo cercando, e se lo utilizzano con successo gli amici della comunità MusicBrainz, allora lo posso utilizzare con successo anch'io. Forse code.google.com è (o diventerà) il repository di riferimento per i moduli Python? Forse l'intenzione è proprio quella: vedremo!

Il codice!

Ho ancora molto dubbi, ma copiando un po' di qua un po' di là, ecco finalmente il mio primo programma Python bello e funzionante:
import win32com.client

from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3

itunes = win32com.client.Dispatch("iTunes.Application")
mainLibrary = itunes.LibraryPlaylist
tracks = mainLibrary.Tracks
numTracks = tracks.Count
n = 1
v = 0

while n <= numTracks:
  currTrack = tracks.Item(n)
  location = win32com.client.CastTo(currTrack,'IITFileOrCDTrack').Location

  if ((currTrack.Artist == "") or (currTrack.Name == "")):
    try:
      m = MP3(location, ID3=EasyID3)
      if m.has_key('artist'):
        currTrack.Artist      = m['artist'][0]
      if m.has_key('album'):
        currTrack.Album       = m['album'][0]
      if m.has_key('title'):
        currTrack.Name        = m['title'][0]
      if m.has_key('tracknumber'):
        currTrack.TrackNumber = m['tracknumber'][0]
      if m.has_key('date'):
        currTrack.Year        = m['date'][0]
      if m.has_key('genre'):
        currTrack.Genre       = m['genre'][0]
      v += 1
    except mutagen.id3.error:
      print "Error"
      continue
  n+=1

print "Brani aggiornati: " + str(v)
Questo programma scorre tutta la libreria iTunes, ed aggiorna il nome dell'artista, il titolo dell'album e del brano, il numero di traccia, la data (uhm forse bisogna estrarre solo l'anno), ed il genere musicale, leggendoli direttamente dai tag del file MP3, per tutti i brani in cui l'artista oppure il brano sono vuoti.
Brutto, sporco, probabilmente buggato, con un cast misterioso e ancora molti perché... ma funzionale: per adesso è un buon inizio!

weRock!

Ho deciso di creare questo blog per raccogliere informazioni che mi possono essere utili e che vorrei poter ricercare in seguito. Non so se potranno essere utili anche a qualcun altro... ma le pubblico lo stesso, non si sa mai!