テクノロジー · 実用ガイド

CalibreのCSV目録に端末だけの本がない?キャッシュから一覧を作る

PCライブラリーの目録では端末だけにある本が抜ける場合があります。キャッシュのコピーを変換し、行数・保存領域・取り込み設定を確認します。

PC目録、端末にある対応済みレコード、キャッシュコピーを比較するイラスト
オリジナルのイラスト:キャッシュコピーはライブラリー目録とは範囲が異なり、クラウド一覧でもありません。 Watch at Ease

リーダー内の本をCSVにしたいとき、PCライブラリーの目録は目的と違う一覧になることがあります。ライブラリーで ondevice:true を使っても対象はそのライブラリーの既存レコードであり、端末だけにある本は追加されません。

読み取り可能な metadata.calibre または .metadata.calibre がある場合、以下ではコピーだけを処理し、電子書籍の内容をPCへ取り込まずに利用可能なキャッシュのレコードを書き出します。クラウドの購入品すべてや、あらゆるリーダーの全ファイルを列挙する保証ではありません。

保存領域を記録してキャッシュをコピーする

端末または管理フォルダーに、Calibre形式のローカルJSONキャッシュがある場合に限って使います。実行中のCalibreの端末スキャンとジョブが終了するのを待ち、対象の保存領域と、フィルターを解除したDevice表示の件数を記録してから、キャッシュを書き換える可能性のあるアプリを閉じます。通常のスキャンではキャッシュが更新されることがありますが、変換処理はPC上のコピーを読むだけです。鑑識用の完全な読み取り専用取得手順ではありません。

キャッシュをPCの新しいフォルダーへ metadata-copy.json としてコピーし、元ファイルは移動しません。元ディレクトリー、保存領域名、コピー時刻を記録します。本体とカードに別のキャッシュがある場合は、それぞれ異なる出力名で処理します。読めるキャッシュがなければこの方法を中止し、PCライブラリーの書き出しを完全な端末一覧と呼ばないでください。このJSONで metadata.db を置き換えません。

キャッシュの1レコードをCSVの1行にする

Python 3がインストール済みなら、コピーのフォルダーで端末を開きます。Windowsでは python3 を py -3 に替えます。次のコマンドを半角の引用符を保ったまま1行としてコピーし、新しい出力ファイル名を選びます。入力はJSON配列で、各レコードの lpath は文字列である必要があります。すべてのレコードを残し、既存CSVは上書きしません。

python3 -c "import csv,json,sys; r=json.load(open(sys.argv[1],encoding='utf-8-sig')); assert isinstance(r,list) and all(isinstance(b,dict) and isinstance(b.get('lpath'),str) for b in r), 'Expected an array of records with lpath'; f=open(sys.argv[2],'x',encoding='utf-8-sig',newline=''); w=csv.writer(f); w.writerow(['row','lpath','title','authors_json','series','series_index']); w.writerows([[i,b['lpath'],b.get('title'),json.dumps(b.get('authors'),ensure_ascii=False),b.get('series'),b.get('series_index')] for i,b in enumerate(r,1)]); f.close(); print(len(r),'cache rows exported')" "metadata-copy.json" "device-cache.csv"

列は row、lpath、title、authors_json、series、series_index です。著者は1セルのJSON値のままなので、複数著者でも行が増えません。null はキャッシュに値がないことを示します。row はこのスナップショット内の順番で、恒久的な本のIDではありません。シリーズの欠落項目は空欄、小数のシリーズ番号はそのままです。不正な入力や既存の出力ではエラーになります。入力を調べるか新しい出力名を選び、元キャッシュを削除して直そうとしないでください。

文字列として取り込み、件数を確かめる

LibreOffice Calcで「ファイル > 開く」から「テキストCSV」を選びます。取り込み画面でUTF-8、区切りはコンマ、文字列区切りは半角の二重引用符を指定します。区切りの結合、空白の除去、数式の評価をオフにし、プレビューの6列すべてをテキストに設定して確定します。画面が省略される場合はファイルを開く画面でフィルター設定の編集を有効にします。これにより元の文字列を保ち、= で始まる題名が数式になるのを防ぎます。

表示されたキャッシュ件数と、ヘッダーを除くCSVのデータ行数を比較します。図の仮想例では3レコードから3行になり、2つのパスが同じでも残ります。引用された題名に改行がある場合があるので、テキストファイルの物理的な行数を数えないでください。重複は調査するまで保ちます。既知の題名、完全な lpath、記録した元の保存領域にある実際のファイルを確認します。コピーしたキャッシュの場所はパスの基準を変更しません。

一覧だけでは証明できないこと

Device表示の項目が抜けたり件数が違ったりしたら、フィルター、選んだ保存領域、スキャン完了、キャッシュの古さを調べます。USB大容量ストレージ用ドライバーは設定されたディレクトリーと対応形式を走査し、全ディスクを網羅するものではありません。古いキャッシュに削除済みファイルが残る場合もあります。同じ題名の2形式は別のファイルレコードで、題名の一致だけでは同じ本や現在のPCライブラリーへの所属を証明できません。

KOReaderもキャッシュを書いて簡略化するため、独自メタデータがないことは本の消失を意味しません。元JSONとCSVを保管し、保存領域とコピー時刻を表示します。この変換コマンドはUnicode、コンマ、複数行の題名、著者のnull、小数番号、重複パス、空配列、不正入力、上書き拒否を含む人工データで実際に検証しました。実機リーダーやCalc画面は検証していません。本のバックアップやクラウド一覧が必要なら、この表だけでは足りません。

重複パスを含む仮想の3キャッシュレコードを示すイラスト
オリジナルのイラスト:仮想の3レコードからCSVの3行を作り、重複パスも残します。 Watch at Ease