2016年3月18日金曜日

Ubuntuにmime typeを追加する/サムネイラを追加する

デスクトップubuntuを使う上で, 独自のファイルタイプを定義したい場合がある. こうすることで特定のファイルに目立つアイコンを割り当てたり, アプリケーションを関連付けたりすることが可能となり, 作業効率の向上が見込めるからだ.

そこで本ドキュメントではxubuntu14.04(+nemo)環境におけるファイルタイプの追加およびカスタマイズについてまとめておくこととする.

まとめておく手順は主に次の2つ
  • mime typeの追加・上書き定義
  • thumbnailerの追加
※なお, (Apacheといった)サーバーとしてのmime typeの追加ではなくてあくまでデスクトップ利用時のtipsである点に注意されたし.

mime typeの追加・上書き定義


ubuntuではファイルタイプをmime typeと言ったもので管理している. これはwindowsでの拡張子に当たるものだが, 拡張子が単にファイル名から得られるものに対し, mime typeはファイル名に加え場合によりファイルの中身(バイナリ)から算出することも可能となっている. そのため, ubuntuではファイル名を変更してもアプリケーションの関連付けが維持されていることがよくある.

大抵のmime typeは予めubuntu側で定義されているが, wine環境でwindowsアプリを稼働させている等, 未知のファイル型に対して独自のmime type型を与えたい場合は次のようにする.

1)/usr/mime/packagesもしくは~/.local/share/mime/packagesにmime typeの定義ファイルを定義する.
※前者はユーザー間で設定を共有する場合に用いる. なお作業にはスーパーユーザー権限が必要.

例えば次のようなxmlファイルを作成し, ~/.local/share/mime/packages/my-setting.xmlとして保存する.

<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
  <mime-type type="audio/gameboy-sound">
    <glob pattern="*.gbs"/>
    <sub-class-of type="application/octet-stream"/>
    <magic>
      <match type="string" offset="0:2" value="GBS"/>
    </magic>
    <generic-icon name="gb"/>
    <comment>GBS オーディオ</comment>
  </mime-type>
</mime-info>

各要素の意味合いは概ね次の通り
  • mime-info mime
    type設定を表すrootノード
  • mime-type mime
    typeを表すノード. type属性にmime type名を指定する. 個人で利用する場合, 命名規則を意識する必要はない筈.
  • glob
    ファイル名で型を判定する際の条件. 大体windowsでの拡張子と思って良い.
  • sub-class-of
    このmime typeが他の型から派生したものの場合に指定する.
    大抵は「application/octet-stream」か「text/plain」となる. 別になくても良いが, アプリの一覧に派生元mime typeに関連付けされたものが表示されるようになる.
  • magic
    mime typeがファイルのバイナリデータ(主にファイルヘッダ)から算出される場合はその条件を表す. 別になくても良い.
  • match
    型判定の条件を記述する. バイナリデータの読み込み位置と比較条件を設定する. match要素を併記した場合はor条件を, match要素をネストさせた場合はand条件を表す.
  • generic-icon
    このmime typeに対応するアイコンを指定する. 既存のシステムアイコン名を指定しても良いが, /usr/share/iconsもしくは~/.local/share/icons直下に自作のアイコンを配置し, それを参照することもできる. 上記は「gb.svg」をアイコンとして利用することとしている.

xmlファイルの詳細については下記を参照
https://specifications.freedesktop.org/shared-mime-info-spec/0.18/ar01s02.html#idm139750563085760
システムに登録されているmime typeはすべて/usr/share/mime/package/freedesktop.org.xmlに記述されているので, 詳しい書き方がわからない場合はこの内容を参考としても良い.


2)update-mime-databaseコマンドを実行し, mime type設定を更新する.
コマンドの実行対象はmime type設定ファイルを保存したディレクトリとする.

update-mime-database ~/.local/share/mime

※なお更新に失敗した場合は設定ファイルを一旦削除し再度コマンドを実行することで元の内容に戻せる. なお誤ったmime type設定がシステムに反映された場合でもアプリの関連付けやアイコンの表示がグチャグチャになるだけで済む.

後は独自のmime typeに対しnemoなりnautilusなりのファイラからアプリの関連付け設定を追加すれば良い.


なお, このmime typeの設定は非常に柔軟に行うことができる. 例えば次のような設定も可能である.
  • 特定の拡張子ファイルに複数の意味付けを与える
    バイナリのdocはofficeファイルでテキストのdocは単なるテキストファイルとして扱うなど. 
  • 特定のファイルタイプに対するアイコンを変更する
    システムで共有されているmime type設定は個人の設定で上書きされる. そのため,特定のファイルタイプに対するアイコンを変更することが可能である.

thumbnailerの追加

 

画像ファイルのアイコンがファイラ上でサムネイル画像として表示されるのは, ファイラの背後でサムネイラと呼ばれる仕組みが動作しているためだ. サムネイラは独自定義することも出来, ソースとなるファイルを画像化する手段があれば, 任意のmime typeのファイルに対してサムネイルを生成・表示させることも可能だ. 例えばhtmlのプレビューをファイラに表示させることもできる. 

以下nemoでの挙動について示す. なおxubuntuの標準ファイラであるthunarでは内容が異なるので注意.

●サムネイラは/usr/share/thumbnailersもしくは~/.local/share/thumbnailersに保管されている. 自作のサムネイラ(ファイル名*.thumbnailer)はここに保存することで即時に有効となる. 例えば下記はxcf画像に対するサムネイラを与える.

#xcf-thumbnailer.thumbnailer
[Thumbnailer Entry]
TryExec=gnome-xcf-thumbnailer
Exec=gnome-xcf-thumbnailer %i %o
MimeType=image/x-xcf;image/x-compressed-xcf;

  • TryExec
    サムネイルを生成するコマンド(存在確認のため) 無くても良い.
  • Exec
    サムネイルの生成コマンド. 引数としては次が与えられる.
    • %i…サムネイルの作成対象のファイルパス
    • %s…サムネイル画像のサイズ(大体128が渡されるっぽい)
    • %o…サムネイル画像の作成先ファイルパス
    複雑なコマンド記述が必要な場合は, 別途自作スクリプトを参照させても良い.
  • MimeType
    サムネイラが処理対象とするファイルのmime typeのリスト. セミコロン区切り.
    既存のサムネイラにおいて特定のファイルタイプのサムネイルが作られない場合は, ここの内容を見直すと良い.

※詳細は下記を参照
https://developer.gnome.org/gnome-desktop3/stable/GnomeDesktopThumbnailFactory.html

※thunarにおいてもサムネイラの独自記述ができるとのことだが, 上手く行かなかった.
http://www.geocities.jp/cabezon_hashimoto/doc/thunar/ja/customizing-thunar.html


●サムネイラによって作成されたサムネイルは「~/.local/cache/thumbnails」に保存される.
サムネイルを再作成する場合は, nemoを強制終了(nemo -qを実行)し, 内部の「normal」等のディレクトリを削除した後にnemoを再起動させる(サムネイル画像のキャッシュがメモリに残っているとサムネイルの再作成が行われないため).

なおサムネイル生成に失敗した場合は「fail」ディレクトリを削除し, F5キーによるディレクトリの再読み込みを行うだけで良い.

※thunarではサムネイル画像が「~/.local/thumbnails」に保存される. nemoとthunarとを並行稼働する場合, 全く同じサムネイル画像が複数箇所に存在することとなる そこで予め「~/.local/cache/thumbnails」から「~/.local/thumbnails」にシンボリックリンクを貼っておくと画像がファイラ間で共有されるため便利である.

---
以下サムネイラの実装例を示す. 


例)サムネイラの実装例:テキストファイルのサムネイラ
※事前にimagemagickとnkfをインストールしておくこと

#text.thumbnailer
[Thumbnailer Entry]
TryExec=nkf
Exec=/home/xxx/.local/share/thumbnailers/text.thumbnailer.sh %i %o
MimeType=text/plain;text/css;application/javascript;application/x-php;・・・

#text.thumbnailer.sh
#!/bin/bash

#font設定
text_font='/home/xxx/.fonts/ipam-mona.ttf';
charset_font='/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-B.ttf'

#改行コード判定
charset=`nkf --guess "${1}"`
if [[ $charset =~ '(CR)' ]] ; then
    nlc='[m]' #new line code
    nlcc='crimson'
elif [[ $charset =~ '(CRLF)' ]] ; then
    nlc='[w]'
    nlcc='darkcyan'
else
    nlc=''
    nlcc='navy'
fi

#文字セット判定
charset=`nkf -g "${1}"`
if [[ ! -s "${1}" ]] ; then
    charset='EMPTY'
    bgc='white'
elif [[ $charset = 'Shift_JIS' ]] ; then
    charset='S_JIS'
    bgc='azure'
elif [[ $charset = 'CP932' ]] ; then
    bgc='mistyrose'
elif [[ $charset = 'EUC-JP' ]] ; then
    bgc='lightyellow'
elif [[ $charset = 'ISO-2022-JP' ]] ; then
    charset='JIS'
    bgc='aliceblue'
elif [[ $charset = 'BINARY' ]] ; then
    bgc='whitesmoke'
elif [[ $charset = 'UTF-8' ]] ; then
    bgc='white'
elif [[ $charset = 'ASCII' ]] ; then
    bgc='white'
else
    bgc='thistle'
fi

#出力内容の取得
if [[ $charset != 'BINARY' ]] ; then
    text=`nkf -w80Lux "${1}" | grep -v '^\s*$' | head -n 10 | sed s/"\t"/" "/g`
else
    text=`nkf -w80 "${1}" | head -c 1000`
fi

#画像生成
#see http://qiita.com/mtakizawa/items/94b4cb6d2da99482c6ac
convert \
    -size 83x104 xc:$bgc \
    -font "$text_font" -gravity northwest -pointsize 10 -fill black -annotate 0x0+0+0 "$text" \
    -bordercolor $bgc -border 3 \
    -size 89x16 xc:white -append \
    -fill $nlcc -font "$charset_font" \
        -gravity "southwest" -pointsize 15 -annotate 0x0+2+0 "$charset$nlc" \
    -bordercolor lightgray -border 1 \
    png32:- > "${2}"

これをテキストファイルに適用するとこんなサムネイルが作られる.(文字コードと改行コードをプレビュー出来るので便利かも)

なおサムネイル化処理が複雑な場合, 相応の負荷がかかることでシステムとしての軽快さが犠牲になるので注意すること.


サムネイラスクリプト作成時の注意

サムネイラから渡されるパラメータには「png画像を生成しろ」と言った内容は含まれていないので, コマンドによっては明示的にpng画像を生成させる必要がある. 上の例では%oで渡されたファイル名に「.png」が含まれておらず, そのままconvertコマンドに渡すと画像形式の判定に失敗する. そのためpng形式の標準出力に画像データを生成してからリダイレクトしている.

追記


頻発するサムネイル画像の削除でrm -rコマンドを暴発してホームディレクトリをふっ飛ばしたのは嫌な思い出. ファイルの削除には細心の注意を…

0 件のコメント:

コメントを投稿