600円で手に入れたオライリー本をKindle向けに全自動変換するWindowsスクリプトを作った
Kindle手に入れて興奮気味です。
そんな中、こんなエントリーが。
たった600円でオライリー本をiPadやKindleで読む。すてき。 - このブログは証明できない。
おー、あの高くて分厚いオライリー本を600円で手に入れてKindleで読める。
id:shunsukさん、詳しく説明されていて、素晴らしい。
読めるオライリー本は英語だけど。あー。
さらに、あのdankogaiさんがスクリプトを作っていたと。
404 Blog Not Found:perl - O'ReillyのiPhoneアプリ本からepubをぶっこぬく
あーこれは自分でもできるかも。
Windows Scripting Host、JScriptで書いてみようかなぁと思って書いたら何とかなった。やった。
Windows XP向けです。Macでは動きません。
導入手順
- http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000234621 から "KindleGen for Windows"をダウンロードして、展開。("I agree to terms of use"のチェック入れてね)
- App2EpubAndMobi.jsをダウンロード(右クリックして「リンク先を保存」で保存してね)、KindleGenを展開したフォルダに放り込みます。
以上。
活用手順
こんな感じでどうでしょう。
今のところ、うちではうまくいっていますが、どうなんでしょう。
あと、.epubファイルをiTunesにドラッグアンドドロップすると、ブックライブラリに登録されたりしますね。
うーん。初代iPod touchユーザーだから.epubファイルは使えないけど。
※600円のオライリー本を買うのをためらってしまい、350円のJavsScriptReferenceでテストしました。
ご注意
目次データは作成されません・・・
こいつはいつかどうにかせねばなぁ。
以下、スクリプトさらし。
プログラム組んでないとすごく時間かかる。
久しぶりであった。
if (WScript.Arguments.Length <= 0) { WScript.Echo('ファイルを指定してください。'); WScript.Quit(); } // extractZipHere(Zipファイル名) var extractZipHere = function(fileInput) { var fso = new ActiveXObject('Scripting.FileSystemObject'); var folderParent = fso.GetParentFolderName(fileInput); var folderExtract = fso.BuildPath(folderParent, fso.GetTempName()); if (!fso.FolderExists(folderExtract)) { fso.CreateFolder(folderExtract); } var shell = new ActiveXObject('Shell.Application'); shell.NameSpace(folderExtract).CopyHere(shell.NameSpace(fileInput).Items()); return folderExtract; } // createZip(作成先のZipファイル名、元のフォルダ名) var createZip = function(fileZip, folderSrc) { var fso = new ActiveXObject('Scripting.FileSystemObject'); var shell = new ActiveXObject('Shell.Application'); fso.CreateTextFile(fileZip); var ofileZip = fso.OpenTextFile(fileZip, 2); // 2 : for Write ofileZip.Write('PK' + String.fromCharCode(5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)); ofileZip.Close(); var ofolderZip = shell.NameSpace(fileZip); var ofolderSrc = shell.NameSpace(folderSrc); var scount = ofolderSrc.Items().count; ofolderZip.CopyHere(ofolderSrc.Items()); while (ofolderZip.items().count != scount ) { WScript.Sleep(100); } } //必要なオブジェクトの生成 var shell = new ActiveXObject('Shell.Application'); var wshell = new ActiveXObject('WScript.Shell'); var fso = new ActiveXObject('Scripting.FileSystemObject'); //指定されたファイルが.ipaファイルか確認 var fileOriginal = WScript.Arguments.Item(0); if (fso.GetExtensionName(fileOriginal) != 'ipa') { WScript.Echo('iPhoneアプリをドラッグ&ドロップしてください。'); WScript.Quit(); } //スクリプトフォルダを取得 var folderScript = String(WScript.ScriptFullName).replace(WScript.ScriptName, ''); //オリジナルファイルを一時フォルダにコピー var folderTmp = fso.GetSpecialFolder(2); var fileInput = fso.BuildPath(folderTmp, fso.GetTempName() + '.zip' ); fso.CopyFile(fileOriginal, fileInput); //zipファイルを展開 var folderExtract = extractZipHere(fileInput); //appフォルダなどの取得 var folderPayload = fso.BuildPath(folderExtract, 'Payload'); //PayLoadフォルダ内の.appファイルのファイル名を取得する(1個しかないはず…) var fileApp = shell.NameSpace(folderPayload).Items().Item(0).Name; var folderApp = fso.BuildPath(folderPayload, fileApp); var folderBook = fso.BuildPath(folderApp, 'book'); var folderOEBPS = fso.BuildPath(folderBook, 'OEBPS'); var fileTOCNCX = fso.BuildPath(folderOEBPS, 'toc.ncx'); //toc.ncxファイルを修正 var ofileTOCNCX = fso.OpenTextFile(fileTOCNCX, 1); // 1 : for Read var strTOCNCX = ofileTOCNCX.ReadAll(); ofileTOCNCX.Close(); //ncx:を削除 strTOCNCX = strTOCNCX.replace(/<ncx:/g, '<'); strTOCNCX = strTOCNCX.replace(/<\/ncx:/g, '<\/'); //一時ファイルを作成 var fileOut = fso.BuildPath(folderOEBPS, fso.GetTempName()); fso.CreateTextFile(fileOut); var ofileOut = fso.OpenTextFile(fileOut, 2); // 2 : for Write ofileOut.Write(strTOCNCX); ofileOut.Close(); //オリジナルファイルを削除し一時ファイルに置き換える fso.DeleteFile(fileTOCNCX); fso.MoveFile(fileOut, fileTOCNCX); //.appフォルダ内をZipに固めて.epubファイルにリネーム var fileZip = fso.BuildPath(folderScript, fso.GetBaseName(fileApp) + '.zip'); createZip(fileZip, folderBook); var fileEpub = fso.BuildPath(folderScript, fso.GetBaseName(fileApp) + '.epub'); if (fso.FileExists(fileEpub)) { fso.DeleteFile(fileEpub); } fso.MoveFile(fileZip, fileEpub); //アトシマツ 一時ファイルを削除 this.CollectGarbage(); //Shell.Applicationがフォルダを離さないことがあるので念のためGC fso.DeleteFile(fileInput); fso.DeleteFolder(folderExtract); //kindlegen.exe に処理を渡す var fileKindlegen = fso.BuildPath(folderScript, 'kindlegen.exe'); wshell.Run(fileKindlegen + ' "' + fileEpub +'"', 1 ,true); WScript.Echo('終了しました。');