きりかノート 3冊め

おあそびプログラミング

ライブラリフォルダにある、iTunesに未登録の不要なファイルを整理する

なんかiTunesのライブラリフォルダのサイズが異常に大きい(iTunesで見る全曲+PodCastのサイズ10GBの3倍以上)ことに気づいた。
以前に母艦(MacBook)のHDDが壊れて、バックアップ(てかiPod)から戻したときに何度かやりなおしたのがうまくなくて、同じ曲のファイルが複数できていたようだ。

無駄だからiTunesのライブラリにないオーディオファイルを削除したいけれど、手作業ではとても無理。

ということでiTunesAppleScript辞書とにらめっこしつつ、RubyOSAを利用したスクリプトファイルを書いた。RubyOSAのサンプルのiTunes/inspect.rbがiTunesのライブラリをリストアップするものなので、これをパクってくればよい。

音楽とそれ以外のライブラリフォルダ(iTunes Library.xmlやアートワークの置き場所)が別になってるとか、自分の環境に依存してる部分もあるのでそのままは使えないと思うけど、いちおうのせとく。
楽曲のファイルは、シェルでエスケープしないとダメな文字がいっぱいあるので、Ruby側のメソッドでファイルの移動・フォルダの作成をするほうが無難。

実行後にiTunesでファイルがないトラックをあらわす(らしい)「!」が曲についてないっぽいことをざっと目視して、移動した不要なファイルを捨てた。

 #!/usr/bin/ruby

require 'rubygems'
require 'rbosa'

ITUNES_LIBRARY_DIR = '/Volumes/QMusic/kimuraw/Musics'
TRASH_DIR = '/Volumes/QMusic/kimuraw/Trash'

# ライブラリフォルダにあるすべてのファイルを列挙
allfiles = Dir.glob(File.join(ITUNES_LIBRARY_DIR, '**/*'))
allfiles.delete_if {|f| File.directory? f}

# rubyosa のinspect.rbから丸パクリ
app = OSA.app('iTunes')
OSA.utf8_strings = true
app.sources.each do |source|
# 「ライブラリ」にある音楽等のファイルパスを取得
source.library_playlists.each do |playlist|
playlist.file_tracks.each do |track|
# if track.enabled?
unless allfiles.delete(path = track.location)
# パスにマッチするファイルがないのは異常
raise "file not found: #{path}"
end
# end
end
end
# はじめのソースだけを処理(iPodが接続されているときに無視する)
break
end

#puts allfiles
#exit # 一度削除対象を確認
require 'fileutils'

def mkdir_p(dir)
unless File.exists?(parent = File.dirname(dir))
mkdir_p(parent)
end
Dir.mkdir dir
end

# 不要なファイルを別階層に移動
allfiles.each do |file|
dest = file.sub(/\A#{ITUNES_LIBRARY_DIR}/, TRASH_DIR)
folder = File.dirname(dest)
mkdir_p folder unless File.exists? folder
FileUtils.move file, dest
end