iTunes Library Updater: Atualizando a biblioteca do iTunes com Ruby

20/11/07

O Mac OS X não tem tem tantas opções de players para música. O mais usado, sem dúvida, é o iTunes. Eu nunca fui muito fã mas na falta de algo melhor, estou tentando me acostumar com ele.

Pensando nisso, fiz um script que atualiza o iTunes, adicionando novos diretórios à biblioteca. Para utilizá-lo, você precisará instalar o RubyOSA, que faz interface com os aplicativos instalados. Basta executar o comando gem install ruby-osa.

Depois, copie o script abaixo — o meu está no diretório "~/Library/Scripts/itunes_updater.rb" — e execute-o uma primeira vez. Isso irá gerar um arquivo em "~/.itunes_updater.yml".

require "rubygems"
require "rbosa"
require "yaml"
 
class ItunesUpdater
  attr_accessor :config_file
  attr_accessor :filters
 
  def initialize
    @itunes = OSA.app('iTunes')
    @pending = []
    @config_file = File.expand_path("~/.itunes_updater.yml")
    @filters = []
 
    parse_config_file
  end
 
  def pending
    libraries.each do |lib|
      lib_folder = File.expand_path(lib)
 
      Dir.entries(lib_folder).each do |artist|
        artist_folder = File.join(lib_folder, artist)
 
        next if skip_folder?(artist_folder)
 
        Dir.entries(artist_folder).each do |album|
          album_folder = File.join(artist_folder, album)
 
          next if skip_folder?(album_folder)
 
          @pending << album_folder
        end
      end
    end
 
    @pending.sort
  end
 
  def update!
    pending.each do |album|
      @itunes.add(album)
    end
 
    @config["updated_at"] = Time.now.to_s
 
    if !save_config_file
      puts "-- unable to save configuration file on #{@config_file.inspect}"
    end
 
    @pending = []
  end
 
  def updated_at
    @config["updated_at"] ? Time.parse(@config["updated_at"].to_s) : (Time.now - (60 * 60 * 24 * 30 * 365))
  end
 
  def libraries
    @config["libraries"] || []
  end
 
  def libraries=(paths)
    @config["libraries"] = paths
  end
 
  def filters
    (@config["filters"] || []).map do |filter|
      filter = File.expand_path(filter)
      filter.downcase
    end
  end
 
  def notify(message)
    title = "iTunes Library Updater"
    image = "/Applications/iTunes.app/Contents/Resources/iTunes.icns"
    system("growlnotify -n itunes_library_updater --image #{image} -p 2 -m \"#{message}\" -t \"#{title}\"")
  end
 
  def create_template
    template = <<YML
updated_at:
libraries: 
  - ~/Music/iTunes/iTunes Music
filters:
  - <ADD THE FOLDER YOU WANT TO SKIP>
YML
    File.open(@config_file, "w+") << template
  end
 
  private
    def skip_folder?(folder)
      # check if folder is represented by . or ..
      return true if folder =~ /\/\.{1,2}/
      # check if is directory
      return true unless File.directory?(folder)
      # check if folder is in the filter list
      return true if filters.include?(folder.downcase)
      # check the modification timestamp
      return true if File.mtime(folder) < updated_at
      # the folder is ok to go
      return false
    end
 
    def parse_config_file
      @config = YAML.load_file(@config_file)
    rescue
      @config = {
        "updated_at" => nil,
        "libraries" => [],
        "filters" => []
      }
    end
 
    def save_config_file
      File.open(@config_file, "w+") do |file|
        YAML.dump(@config, file)
      end
 
      return true
    rescue
      return false
    end
end
 
if $0 == __FILE__
  itunes = ItunesUpdater.new
 
  if File.exists?(itunes.config_file)
    pending_items = itunes.pending.size
 
    if pending_items > 0
      itunes.notify("#{pending_items} pending folder(s)")
      itunes.update!
      itunes.notify("Library updated!")
    else
      itunes.notify("No pending items found")
    end
  else
    itunes.create_template
    itunes.notify("The configuration file has been created.\n\nIf you need to customize it, edit the file #{itunes.config_file}")
  end
end

Por padrão, o script verifica o diretório "~/Music/iTunes/iTunes Music", local onde são salvas todas as músicas. Eu deixo o iTunes configurado para não copiar as músicas (minhas músicas ficam em um outro diretório, onde os mp3s são colocados após passar pelo MusicBrainz ~ sim, sou um fanático). Se você deixa seus arquivos em outro local, não se esqueça de alterar o arquivo "~/.itunes_updater.yml".

updated_at:
libraries: 
  - ~/Music/MP3
filters: 
  - ~/Music/MP3/_Temporary
  - ~/Music/MP3/tagged
  - ~/Music/MP3/UNTAGGED

Para atualizar sua biblioteca, basta executar o comando ruby itunes_updater.rb. Lembre-se de executar o arquivo do lugar onde você o salvou. Após atualizar sua biblioteca, uma notificação será exibida.

iTunes Library Updater

Este script também está no meu repositório: svn.simplesideias.com.br/general/ruby/itunes_updater.rb

Comentários #


#1 EAD disse:
30 Nov 07, 02:26PM

Esse tipo d linguagem eu ñ lembro pelo q me parece deve ser linguagem C,C++

#2 Pedro Valentini disse:
07 Dez 07, 07:53PM

me parece ruby EAD…

quanto ao script não entendi uma coisa, se arrastar as músicas para o itunes ele já não faz isso? insere as músicas na biblioteca?
aqui eu faço isso, só arrasto elas para o itunes e configurei para ele manter a biblioteca consistente então ta resolvido, depois de arrastar pro itunes eu apago os arquivos e eles ficam na pasta única q eu escolhi atualizados ;) o negocio foi bem feito

hummm 4+2 ?

#3 Nando Vieira disse:
07 Dez 07, 08:07PM

Pedro, o problema é que não quero ter que fazer isso manualmente. Eu deixei um job rodando no background para adicionar tudo para mim! ;)

#4 Andre L. Soares disse:
14 Dez 07, 12:55PM

Também tentei aqui e não deu certo. Mas, no meu caso, deve ser porque entendo menos do que o necessário. De qualquer modo, adoor o iTunes. Um abraço!

#5 Iraê disse:
11 Jan 08, 11:08AM

Também tem o menu "File > Add Folder to Library" que faz exatamente isso se você escolher o folder pai de todos esses… =D

Deixe um comentário




Este blog usa o Gravatar.


Não é aceito código HTML:
adicione-o no pastie.caboo.se ou paste.milk-it.net e poste apenas o link.

Se este é seu primeiro comentário, ele terá que ser aprovado antes de ser exibido.