giovedì, febbraio 26, 2009

 

Sync due cartelle di mp3

Mi sono ritrovato con due cartelle zeppe di mp3 praticamente uguali. Il dubbio è stato quello di troncare una delle due cartelle, oppure... trovare i file non presenti nella cartella principale e cancellare tutto il resto.

Alla fine ho estratto questo script:

#!/usr/bin/ruby
#

require 'find'
require 'mp3info'
require 'fileutils'

class Mp3
attr :stat
attr :fullname
attr :info

def initialize(fname)
@fullname = fname
@stat = File.stat(@fullname)
begin
@info = Mp3Info.new(@fullname)
rescue Errno::ENOENT
@info = nil
end
end

def ==(o)
if (@info and o and o.info )
return ((o.info.tag1.title == @info.tag1.title) and (o.info.tag1.artist == @info.tag1.artist))
else
return o.name == name
end
end

def name
File.basename(@fullname)
end

def dirname
File.dirname(@fullname)
end

def to_s
@fullname
end

end

class Mp3List

attr :lista
attr :basedir

def initialize(base = ".")
@basedir = base
@lista = []
end

def walk
Find.find(@basedir) do
|f|
next unless File.file?(f)
next unless File.extname(f) == ".mp3"
next if File.basename(f) =~ /^\./
mp3 = Mp3.new(f)
@lista << mp3 unless @lista.include?(mp3)
end
end

def each
@lista.each do
|item|
yield item
end
end
end

lista_locale = Mp3List.new("/data/documenti/Musica")

pool = []
pool << Thread.new {
puts "Elaborazione lista locale..."
lista_locale.walk
puts "Locale: trovati #{lista_locale.lista.size} mp3"
}



lista_server = Mp3List.new("/mnt/server/Musica")
pool << Thread.new {
puts "Elaborazione lista server..."
lista_server.walk
puts "Server: trovati #{lista_server.lista.size} mp3"
}

pool.each { |t| t.join }

da_copiare = []

puts "Inizio diff..."
lista_locale.each do
|lcl|
da_copiare << lcl unless lista_server.lista.include?(lcl)
end

puts "Trovati #{da_copiare.size} file da copiare"

File.open("da_copiare", "w") do
|f|
da_copiare.each { |i|
$stdout.puts i.fullname
relativepath = i.fullname.gsub(Regexp.new(lista_locale.basedir),'')
FileUtils.mkdir_p File.dirname(i.fullname)
FileUtils.cp i.fullname, File.join(lista_server.basedir, relativepath), :verbose => true
FileUtils.rm i.fullname, :verbose => true, :noop => true
lista_locale.delete(i)
}
end


E' necessario l'installazione della gemma ruby-mp3info.

Commenti: Posta un commento

Iscriviti a Commenti sul post [Atom]





<< Home page

This page is powered by Blogger. Isn't yours?

Iscriviti a Post [Atom]