のらぬこの日常を描く

ノージャンルのお役立ち情報やアニメとゲームの話、ソフトウェア開発に関する話などを中心としたブログです。

PT3で録画したアニメをrubyを使ってタイトルごとに自動で振り分ける

お題

今日は、フラットに保存されたファイルを自動でカテゴライズしてフォルダ分類する方法を考えてみます。

前置き

  • 1年半ほど前からPT3を運用しています。
  • 録画したファイルは深夜3時頃から .mp4に変換してNAS状の所定ディレクトリに自動でコピーしています。
  • ちなみにファイル名は 『番組タイトル(放送局から送られてくる物)_放送局_日時.mp4』というルールにしています。
  • 問題はすべてのアニメを同一フォルダにコピーしているため録画フォルダが煩雑になっているということです。
  • エクスプローラで見るとこんなかんじです。
    • f:id:mikenekoDX:20140604020210p:image
  • もうちょっと整理したいです。
  • 今回は、これらのファイルをアニメタイトルごとにフォルダ分けしたいと思います。

当然・・・

  • 手作業とかめんどくさいので自動振り分けでやりたいです。
  • なんかスクリプトとか書いて、あとはそいつに全部お任せしたいです。
  • もちろんこれからも自動振り分けにしたいので、後からでもある程度は手直しできるレベルのものを作ります。

実現手段

  • 難しいことを考えずに書けるのでやっぱりRubyを使うことにしました。
  • 作ったソースはこんなかんじです。
ruby 1.9.3p362 (2012-12-25) [i386-mswin32_100] で動作確認済。
1.8.x 系とか 2.0 系は動くか不明。

#!/usr/bin/ruby
# coding: utf-8
# script.name categorize_dir.rb

# 使い方
# categorize_dir.rb <録画保存ディレクトリ>
# 例) categorize_dir.rb c:\録画先

require 'fileutils'

INPUT_DIR = ARGV[0].gsub("\\", "/").encode("utf-8")

files = Array::new

Dir.glob("#{INPUT_DIR}/*") do |file|
	if File.directory?(file)
		next
	end
	f = File.basename(file).encode("utf-8")

	directory = ""
	
	# ファイル名から地デジ等の番組情報から取得した放送タイトルを抽出
	title = f.split(/_/)[0]

	# 放送タイトル情報から アニメのタイトル部分を抽出
	title.split(/ | /).each do |fp|
		isEnd = false
		if fp.split(/#|♯|「/).size > 1 then
			if directory.length + fp.split(/#|♯|「/)[0].length > 0 then
				fp = fp.split(/#|♯|「/)[0]
				isEnd = true
			end
		end
		if /^#[0-9]+$/.match(fp) != nil || /^#|♯|喪[0-90-9]+$/.match(fp) != nil ||
			/^第[0-90-9]+話|柱$/.match(fp) != nil then
			break
		else
			directory += " " + fp
		end
		if isEnd then
			break
		end
	end

	# 移動先ディレクトリを確定する
	newDirectory = "#{INPUT_DIR}/#{directory.strip.encode("utf-8")}"
	print "#{f} => #{newDirectory}\n"

	# ディレクトリがなければ作成
	if !FileTest.exist?(newDirectory) then
		print "[CREATE DIR] #{newDirectory}\n"
		FileUtils.mkdir_p(newDirectory)
	end

	# ファイルを移動
	FileUtils.mv("#{I♯NPUT_DIR}/#{f}", "#{newDirectory}/#{f}")
end

スクリプト実行後

  • スクリプトを実行すると、自動でアニメタイトルのフォルダが作られ、ファイルが各フォルダに移動します。
  • 実行後に録画フォルダを開くとこんな風になっています。
    • スクリプトを実行しただけで、それ以外に手は加えていません。たぶん。
    • f:id:mikenekoDX:20140604020211p:image
    • f:id:mikenekoDX:20140604020212p:image

一応スクリプトの補足とか説明とか

大枠はソース読んでください。

番組タイトル情報から アニメのタイトル部分を抽出の部分はそれなりに頑張ってます。

放送局から送られてくる番組タイトルは、アニメによってかなりゆらぎがあるので、ここからなんとなくアニメタイトルを抽出する必要があります。

番組タイトル=アニメタイトル となっていれば楽なのですが、アニメタイトル、話数、サブタイトルが、割と適当なフォーマットで入っていたりするので、スクリプト側でうまいことアニメタイトルを抽出しなければならないのです。

例)

  • 帰宅部活動記録 「記録の二十四『姉と弟』他」#8 → 帰宅部活動記録
  • 恋愛ラボ ♯9 → 恋愛ラボ
    • 話数を表す シャープ記号も、「#」と「♯」」、2パターンあるんです。。
  • ダンガンロンパ 希望の学園と絶望の高校生 The Animation #2 → ダンガンロンパ 希望の学園と絶望の高校生 The Animation
    • タイトルに空白(スペース)が含まれていても、どこまでがタイトルなのかをなんとなく把握します。


対応できないパターンが今後出てきたら、スクリプトいじって何とかする感じですかね。