Hatena::ブログ(Diary)

いたさんの日記

2010-08-13

O'ReillyのiPhone AppからEPUBファイルを抽出するRubyスクリプト

404 Blog Not Found:perl - O’ReillyのiPhoneアプリ本からepubをぶっこぬくを参考に、Ruby版を作ってみるテスト


#/usr/bin/env ruby

def deleteall(delthem)
  if FileTest.directory?(delthem) then  # ディレクトリかどうかを判別
    Dir.foreach( delthem ) do |file|    # 中身を一覧
      next if /^\.+$/ =~ file           # 上位ディレクトリと自身を対象から外す
      deleteall( delthem.sub(/\/+$/,"") + "/" + file )
    end
    Dir.rmdir(delthem) rescue ""        # 中身が空になったディレクトリを削除
  else
    File.delete(delthem)                # ディレクトリでなければ削除
  end
end

def clean
  deleteall('Payload')
end

def die(message)
  puts message
  exit(1)
end

$src = ARGV.shift
die "Usage:#{$0} src.ipa [dst.epub]" unless $src && File.exist?($src)

$dst = ARGV.shift
unless $dst
  $dst = File.basename($src)
  $dst = $dst.sub(/\w+$/, 'epub')
end

result = `unzip -q #{$src} -x iTunes*`
die result unless $?.exitstatus == 0

$app = Dir.glob("Payload/*.app/book").first
die "No book found in the archive" unless $app

Dir.chdir($app) do |path|
  $updir = '../../..'
  system "zip", "-q0X", "#{$updir}/#{$dst}", 'mimetype'
  system "zip", "-qXr9D", "#{$updir}/#{$dst}", "META-INF", "OEBPS"
end
clean
system "open", "-a/Applications/iTunes.app", $dst

Rubyには中身が空でないディレクトリを一発消去する方法がないので、逆引きRuby - ディレクトリ:中身が空でないディレクトリを削除する からメソッドを借りてきました。

また、dieがなくてifが多くなるのが嫌だったので、自前でdieメソッドを追加。

使い方は弾さんのPerl番と同じ。上記のスクリプトをipa2epubとでもして実行権を与え、

ipa2epub path/to/ipa

で、EPUBを作成し、iTunesに登録できます。

[訂正]

Rubyには中身が空でないディレクトリを一発消去する方法がない は間違いでした。FileUtilsライブラリがあるので、これを使えばPerl版とほぼ同じような記述が可能でした。

#/usr/bin/env ruby
require "fileutils"

def clean
  FileUtils.rmtree('Payload')
end

def die(message)
  puts message
  exit(1)
end

$src = ARGV.shift
die "Usage:#{$0} src.ipa [dst.epub]" unless $src && File.exist?($src)

$dst = ARGV.shift
unless $dst
  $dst = File.basename($src)
  $dst = $dst.sub(/\w+$/, 'epub')
end

result = `unzip -q #{$src} -x iTunes*`
die result unless $?.exitstatus == 0

$app = Dir.glob("Payload/*.app/book").first
die "No book found in the archive" unless $app

Dir.chdir($app) do |path|
  $updir = '../../..'
  system "zip", "-q0X", "#{$updir}/#{$dst}", 'mimetype'
  system "zip", "-qXr9D", "#{$updir}/#{$dst}", "META-INF", "OEBPS"
end
clean
system "open", "-a/Applications/iTunes.app", $dst