Nautilus」タグアーカイブ

Linux shift-jis zip file

とある ZIP を展開しようと思ったら Shift-JIS ファイル名を使っていて展開できない。
Ubuntu 日本語 Remix 付属の /usr/bin/zip なら展開できるのだけど Fedora だし。
仮想マシンの Ubuntu から頂いて、と思ったけど我が Fedora は 64bit だった…

仮想マシンな Windows XP から共有を利用して展開。
とソレだけの理由で仮想 Windows を立ち上げるのも面倒だ。
そういえば Python には zipfile モジュールがある、作ってみよう。

とりあえず日本語のドキュメントを探してみた。
13.4. zipfile ? ZIP アーカイブの処理 ? Python v2.6.2 documentation
extractall なんて便利なメソッドがあるじゃん、これは簡単そうだ。
ということで Nautilus スクリプトにしてみた。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import zipfile
import os

filenames = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")

for f in filenames:
    z = zipfile.ZipFile(f)
    z.extractall()
    z.close()

こんなに単純なコードでいいみたい。
ファイル名は見事に化けてしまいますが展開だけは成功する。

そういえばパスワード付きの場合もある。
GTK+ でダイアログでも出して入力すればいいかな。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import zipfile
import os
import gtk

filenames = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")

for f in filenames:
    z = zipfile.ZipFile(f)
    dlg = gtk.Dialog("password", None, 0, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    def dlg_ok(self):
        dlg.response(gtk.RESPONSE_ACCEPT)
    entry = gtk.Entry()
    entry.connect("activate", dlg_ok)
    dlg.vbox.pack_start(entry)
    dlg.show_all()
    dlg.run()
    p = entry.get_text()
    dlg.destroy()
    z.extractall(pwd=p)

展開が終了するまでダイアログが閉じないのは何故だろう…
それと展開は死ぬほど遅い…

せっかく作ったけど素直に仮想 Windows から展開するとかのほうが良さそう。
まあ使いたくなる場合もあるだろうからスクリプト登録だけはしておくか。

ところで今頃気がついた。
Nautilus スクリプト位置にディレクトリを作れば入れ子にできるんだね。

まだまだ増やしても大丈夫そうだ。

MP4 Container get_m4a Nautilus Script

以前 MPEG4 動画から AAC を抜く Nautilus Script にこんなことを書いた
BlackBerry Ubuntu Connect

これだと再生時間が変な表示になるしタグ編集もできない。
理由が解らなかったけど何を今ごろこんなのを見つけた。

iTunesのライブラリにAACファイルが追加できない | OKWave

そうか、素の AAC でなく MP4 コンテナとして抜かないと駄目なのか。
一応動画プレイヤーを作っている人なのにこんなのも知らないでいいのか俺…
とにかく、ならば ffmpeg に -vn オプションを付け拡張子を m4a 指定でイケそうだ。

#FFCOMMAND = "ffmpeg -y -i %s -acodec copy %s.aac"
FFCOMMAND = "ffmpeg -y -i %s -vn -acodec copy %s.m4a"

ついでに debug 用の表示メッセージボックスのコードも入れて
コマンド出力の確認をしたい場合はコメントアウトを外せばダイアログが出る。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
    get_m4a.py Nautilus Script
"""


import os
import commands
import gtk

FFCOMMAND = "ffmpeg -y -i %s -vn -acodec copy %s.m4a"

def debug_message(text, title):
    dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, text)
    dlg.set_title(title)  
    dlg.run()  
    dlg.destroy()

path_array = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")
for f in path_array:
    pos = f.rindex(".")
    r = commands.getoutput(FFCOMMAND % (f, f[:pos]))
    #debug_message(r, "Get AAC Message")

うん、コレなら再生時間も正しいし Rhythmbox でタグ編集も可能になった。
ついでに以前のコマンドで抜いた AAC もそのまま丸ごと m4a に変換できる。

もちろん BlackBerry で再生…
音が飛ぶんだが…

素の AAC なら飛ばないけど再生時間表示が Rhythmbox での算出と違う。
なんだよコレ、get_aac.py は残して追加するほうがいいな。

ついでに以前書いた Nautilus の場所バー直接入力切り替えだが。
Mandriva to Ubuntu p3
Ctrl+L でよかったのね、戻すには Esc でいい。
toggle.sh はもういらないな、つか一度も使ったことが無いような…
Linux に慣れると端末から Tab キー保管が簡単にできるディレクトリ名にしちゃうからね。

Nautilus と Dolphin と GnomeVFS

Nautilus の D&D で送られてくる text/uri-list で何を今頃気がついた。
これって CRLF 区切りなのか、Dolphin の場合は LF 区切りの URI が送られてくる。

ぱぇぽぃ2 ? Blog Archive ? Get MIME Type and Description

上記に書いたコードのように今まで URI の最後の一文字を削除していた。
たまたまそうやったら上手くいったからずっとそうしてきただけだったりする。
CR の存在を今まで知らずにアプリを作っていたのか、反省。
ということは

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import gtk
import gnomevfs

class MimeWin2(gtk.Window):
    """
        Showing MIME Type and Description of Dropped file
    """
    def __init__(self):
        gtk.Window.__init__(self)
        dnd_list = [("text/uri-list", 0, 0)]
        self.drag_dest_set( gtk.DEST_DEFAULT_MOTION |
                            gtk.DEST_DEFAULT_HIGHLIGHT |
                            gtk.DEST_DEFAULT_DROP,
                            dnd_list, gtk.gdk.ACTION_MOVE )
        self.connect("drag_data_received", self.on_drop)
        self.label = gtk.Label("Drop")
        self.add(self.label)
        self.connect("delete-event", gtk.main_quit)
        self.resize(320, 150)
        self.show_all()

    def on_drop(self, widget, context, x, y, selection_data, info, time):
        if "\r\n" in selection_data.data:
            drops = selection_data.data.split("\r\n")
        else:
            drops = selection_data.data.split("\n")
        for drop in drops:
            if not drop == "":
                name = drop
                mime = gnomevfs.get_mime_type(name)
                desc = gnomevfs.mime_get_description(mime)
                self.label.set_text("MIME Type = %s\nDescription = %s" % (mime, desc))

if __name__ == "__main__":
    w = MimeWin2()
    gtk.main()

gnomevfs

こうすれば Nautilus でも Dolphin でも対応できるじゃないの。
てか改行コードが違うだけで text/uri-list が送られてくるのは同じなのか。
KDE の Mandriva でも GnomeVFS から普通に MIME Type を取得できるのは驚いた。
ま、そうじゃないと Firefox や Totem が動かせないか、納得。

ところでスクリプトの扱いが Nautilus と Dolphin では随分違うなぁ。
シェルスクリプトだと実効パーミッションでもダブルクリックで実効できない。
Python スクリプトだと逆に Nautilus のように質問は無くていきなり実効してしまう。
bash からだとまったく同じ、そりゃそうか。

私が実効スクリプトを分けて配布しているのは完全に自分の都合。
python スクリプトをダブルクリックだけで gedit で開けるからという単純な理由です。
Mandriva で使うことを考えて実効スクリプトを Python スクリプトにすればいいかなと。

ということでソコを書き換えたら Y901x は再生できるようになった。

baseboll

後は dbus と wnck をなんとかすれば Mandriva もサポートできる。
リポジトリにはあるんですけどね。

python_dbus

Get MIME Type and Description

ファイル情報取得で MIME Type を取得したい、その2。

GnomeVFS – Wikipedia
[mew-dist 24325] Re: Content-typeの取り扱いについて

なんだ、gnomevfs ってのを使えばいいのか。

gnome-vfs python – Google Search
Python gnomevfs Reference Manual

簡単に見つかった、メリケンの google が便利すぐる。

Finding the MIME type of a file – Community Ubuntu Documentation

方法まであっさり、しかし他国でこの手を探すと Python コードがすぐ見つかる。
日本ってこんなことでもガラパゴス状態なんだよなぁと。
しかしファイルの種類は日本語での取得ができるのかな?試してみよう。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import gtk
import gnomevfs

class MimeWin2(gtk.Window):
    """
        Showing MIME Type and Description of Dropped file
    """
    def __init__(self):
        gtk.Window.__init__(self)
        dnd_list = [("text/uri-list", 0, 0)]
        self.drag_dest_set( gtk.DEST_DEFAULT_MOTION |
                            gtk.DEST_DEFAULT_HIGHLIGHT |
                            gtk.DEST_DEFAULT_DROP,
                            dnd_list, gtk.gdk.ACTION_MOVE )
        self.connect("drag_data_received", self.on_drop)
        self.label = gtk.Label("Drop")
        self.add(self.label)
        self.connect("delete-event", gtk.main_quit)
        self.resize(320, 150)
        self.show_all()

    def on_drop(self, widget, context, x, y, selection_data, info, time):
        drops = selection_data.data.split("\n")
        for drop in drops:
            if not drop == "":
                name = drop[:-1]
                mime = gnomevfs.get_mime_type(name)
                desc = gnomevfs.mime_get_description(mime)
                self.label.set_text("MIME Type = %s\nDescription = %s" % (mime, desc))

if __name__ == "__main__":
    w = MimeWin2()
    gtk.main()

mime_win2

うん、これなら拡張子無しでもなんでも完璧に Nautilus と同じだ。

dir(gnomevfs)

で見ると更にオイシソウなメソッドが見つかりますね。
ファイル情報取得はこれだけでイケそうです。
ただ GNOME 限定になるのはしかたがない。

Enjoy!

Get MIME Type

ファイル情報取得で MIME Type を取得したい。
mimetypes モジュールでは拡張子判別しかできないみたいですけど。
Nautilus は拡張子が優先だけど無くても取得できているじゃないか。
ということで地味に方法を探してみる。

ファイルの MIME タイプの検出 (GNOME 2.2 システム管理 (Linux 版)) – Sun Microsystems

/etc/gnome-vfs-mime-magic
/etc/mime.types

のファイルが元ということになっているみたいなんだが Ubuntu では

ubuntuで対応しているMIME Typeを調べるには:Linux つれづれ日記:So-net blog

/usr/share/mime 以下なのか。
xdg-mime は MIME Types のインストール関連に使うものだがどっちに登録するのかな?

つーか Nautilus が取得できているんだから絶対にシェルから取得できるはずだ。
色々調べていたらこんなのを見つけた。

Nautilus File Manager Scripts: File Information Querying Scripts

file コマンドだけでこんなことができるのか。

$ file --help

で調べると –mime-type オプションがあるらしい、それならこうしてみよう。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import gtk
import urllib
import os.path
import commands

class MimeWin(gtk.Window):
    """
        Showing MIME Type of Dropped file
    """
    def __init__(self):
        gtk.Window.__init__(self)
        dnd_list = [("text/uri-list", 0, 0)]
        self.drag_dest_set( gtk.DEST_DEFAULT_MOTION |
                            gtk.DEST_DEFAULT_HIGHLIGHT |
                            gtk.DEST_DEFAULT_DROP,
                            dnd_list, gtk.gdk.ACTION_MOVE )
        self.connect("drag_data_received", self.on_drop)
        self.label = gtk.Label("Drop")
        self.add(self.label)
        self.connect("delete-event", gtk.main_quit)
        self.resize(320, 150)
        self.show_all()

    def on_drop(self, widget, context, x, y, selection_data, info, time):
        drops = selection_data.data.split("\n")
        for drop in drops:
            name = urllib.unquote(drop)[7:-1]
            if os.path.isfile(name):
                # Get MIME Type
                mime = commands.getoutput("file --mime-type %s" % name)
                self.label.set_text(mime)

if __name__ == "__main__":
    w = MimeWin()
    gtk.main()

ext_non

おお、しっかり取得してくれているじゃないか。
しかし Python Script では

ext_py

text/x-java …
text/x-python のはずなのに、ダメだこりゃ。

mime = mimetypes.guess_type(name)[0]
if mime:
    self.label.set_text(mime)
else:
    self.label.set_text("Non Extension")

ならキチンと text/x-python になる、しかし拡張子が無いなら None になる。
んーどっちも使えない、もうちょっと調べます。

Enjoy!