僕の iTunes ライブラリには10年以上ためこんだ音楽が入っているが、例えばカラオケトラックやドラマCDなどは普段聴かないので除外している。
iTunes ではこれをスマートプレイリストで実現しているが、今回はこれをファイルベースでやる必要が出てきた(聴くものだけSDカードにコピーしたかった)ので、Ruby でサクッとスクリプトを書いてみた。
copy_musics のブロックで条件付けを後からいろいろ変更できるようにしたつもり。
Gemfile
source :rubygems gem "taglib-ruby", "~> 0.7.1"
スクリプト
require 'taglib' require 'find' require 'fileutils' def is_file_equal?(source, destination) if !File.exist?(destination) return false end if FileTest.size(source) != FileTest.size(destination) return false end if File.mtime(source) < File.mtime(destination) return false end return true end def copy_musics(input_dir, destination_dir) Find.find(input_dir) do |source_path| target_path = destination_dir + source_path.slice(input_dir.length, source_path.length) if FileTest.directory?(target_path) next end if is_file_equal?(source_path, target_path) next end if FileTest.zero?(source_path) next end check = false TagLib::FileRef.open(source_path) do |fileref| unless fileref.null? check = yield(fileref.tag, source_path) end end if !check next end puts target_path target_dir = File.dirname(target_path) if !Dir.exist?(target_dir) FileUtils.mkdir_p(target_dir) end FileUtils.cp(source_path, target_path) end end input_dir = ARGV[0] destination_dir = ARGV[1] copy_musics(input_dir, destination_dir) do |music| album = music.album title = music.title artist = music.artist genre = music.genre # カラオケ next false if title =~ /off vocal/i || title =~ /vocal off/i || title =~ /karaoke/i || title =~ /カラオケ/i || title =~ /からおけ/i || title =~ /without/i || title =~ /いないver\./i || # ひぐらしのCDにあった title =~ /[\(-]inst/i || title =~ /Instrumental/i # ドラマCD next false if album =~ /ドラマCD/ || album =~ /サウンドステージ/ || album =~ /サウンドブック/ # アイマスのドラマパート・サントラ next false if album =~ /IDOLM@STER/i && ( title =~ /トーク ?\d\d/ || title =~ /トラック ?\d\d/ || title =~ /SCENE ?\d\d/ || title =~ /ボーナス・トラック/ || title =~ /^ドラマ/ || title =~ /^DRAMA/i || album =~ /IDOLM@STER STATION/i || album =~ /THE IDOLM@STER ANIM@TION MASTER/i ) # サウンドトラックを除外 ただし "Princess Piccolo" Original Soundtrack -2nd Edition- は残す next false if ( album =~ /サウンドトラック/ || album =~ /サントラ/ || album =~ /soundtrack/i || album =~ /sound track/i || album =~ /O\.S\.T/i ) && (album !~ /Princess Piccolo/) # そもそもアルバム名が入ってない next false if album == "" true end
つかいかた
$ bundle exec ruby musicsync.rb ~/Music/iTunes/iTunes\ Music/Music /Volumes/Musics/Musics