Python」タグアーカイブ

register_sinkfunc

Y901x を機動すると以下の推奨メッセージが出るようになった。

** Message: pygobject_register_sinkfunc is deprecated (GstObject)

問題なく動くからあまり気にしていなかったけどそろっそろ…
海外を探しても関係ないバグ情報ばかりで困っていたのだが…

ふと思いついて rhythmbox で試してみても同じだった。

どうせ見つからないと思うけど日本語で探してみた。
んー、これはもしかしなくても ATI なのが悪いのかな。

Ubuntu日本語フォーラム / Moovidaメディアセンターが起動できません

ということで GStreamer がおかしいのだろう。
お手上げだ。

ついでに発見。
Y901x のフルスクリーンは全体サイズをフルスクリーンにしていた。
けど GDK だけフルスクリーンでもイケたと何を今更知った。
GtkBox に配置しているパーツは hide しなきゃいけないみたいだけど。

def change_fullscreen(self):
    if self.p_filename == "":
        return
    if self.fullscreen:
        self.fullscreen = False
        self.w.window.unfullscreen()
        #self.w.unfullscreen()
        self.fullobj.destroy()
        self.fullobj = None
        self.menubar.show()
        if self.full_list:
            self.listbox.show()
        #self.w.resize(self.fullsize.width, self.fullsize.height)
    else:
        self.fullscreen = True
        #cx, cy = self.w.get_size()
        #self.fullsize.width = cx
        #self.fullsize.height = cy
        self.full_list = self.listbox.get_property("visible")
        if self.full_list:
            self.listbox.hide()
        self.menubar.hide()
        self.fullobj = CFullCtrl(
                self.hbox_ctrl,
                self.toolbox,
                self.vbox_main,
                self.statusbar
            )
        #self.w.fullscreen()
        self.w.window.fullscreen()

つまり gtk.Window.window.fullscreen() 処理だけでよかった。
全体をフルスクリーンにして後でサイズを戻す処理は必要ないんだね。

コレならフルスクリーン中にリストを出す処理も簡単に実装できるかな?
そういえばリストを下に移動する処理を入れるって前書いたっけな。
ユーザーは多分自分だけだと思うからどうするのも勝手だけど。

WebKit for Python

Ubuntu 10.10 のアップデート、61MB もあるんかい!
ってよく見たら libwebkit なんてのがあるんだけど…

WebKit な Epiphany は GNOME 標準だけど Ubuntu では除かれているのに。
ライブラリだけは存在しますということなのかな?
まてよ、そういうことならデフォルト状態で Python から使えるかも。

>>>import webkit

10.10 はデフォルトで利用できるようです、てゆーか
/usr/share/doc/python-webkit/examples/browser.py
にサンプルコードがあるわな。

このサンプルコードを試してもいいけど最小限のコードを書いてみる。

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

import gtk
import webkit

class WebKitTest(gtk.Window):
    """
        WebKit test for Python
        from Ubuntu 10.10
    """
    def __init__(self):
        # Window
        gtk.Window.__init__(self)
        self.connect("delete-event", gtk.main_quit)
        self.resize(640, 480)
        # WebKit
        w = webkit.WebView()
        w.load_uri("http://google.co.jp/")
        # ScrollWindow
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        # add
        sw.add(w)
        self.add(sw)
        self.show_all()

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

おぉ、コレだけで使えるのか。
GtkScrolledWindow を噛まさないと縦長のページで悲惨になるので注意ね。
後はサンプルコードを見ながらチマチマ弄くれば立派な自作ブラウザになりそう。

とにかく Python だけで何でも作れてしまう。
デフォルト状態でも作って遊べるというのはやはり素晴らしい。
Windows ではこんなこと考えられないものなぁ。

text in liststore

そろそろ Y901x に機能追加をしようと先日より少しづつ弄くっております。
作った本人以外に使っている人がいないかもしれないがイイじゃないか。
少なくとも作っている本人は使っているんだから。

とりあえずファイルリストを Y901 と同様な下に位置変更できるようにしたい。
変更方法は Y901 と同じリストの右クリックメニューと Ctrl+F12 でいいだろう。
ということでリストに右クリックメニューを付けて上手く動くか実験中。
位置変更は空の GtkBox を配置してパレント変更するだけなので難しくないと思う。

そういえば現行では辞書で保持している設定を __slots__ 付き class に変更したい。
そうしておいたほうが後々の変更で凡ミスを防げる確率が高くなるはず。

self.setting = {"mimes": mimes,
                "position": False,
                "init_size_on": False,
                "init_size_val": 0,
                "esc_exit": False,
                "mem_rep": False,
                "mem_aspect": False,
                "loop": False,
                "severity": 25,
                "aspect_rate": [1,1],
                "set_size": [[320,240],[640,480],[1280,720]]}

# ↓

class CSetting(object):
    __slots__ = [
            "mimes", "position", "init_size_on", "init_size_val", "esc_exit",
            "mem_rep", "mem_aspect", "endressloop", "severity", "aspect_rate",
            "set_size"]
    def __init__(self):
        self.mimes = MIMES
        self.position = False
        self.init_size_on = False
        self.init_size_val = 0
        self.esc_exit = False
        self.mem_rep = False
        self.mem_aspect = False
        self.endressloop = False
        self.severity = 25
        self.aspect_rate = [1,1]
        self.set_size = [[320,240],[640,480],[1280,720]]

定数扱いなのに小文字だった mimes とかはキチンと大文字に変えて…
loop とか自分でもドレに相当するか解りにくい変数名は解りやすく変えて…
今になって見ると我ながら初心者丸出しで切ないよ。

setting[

で検索して地味に手書きで書き換えたけどドットを忘れるとかで間違えまくる。
ドット忘れだと動的言語は新規変数と扱ってしまうから間違いを見つけるのが大変。
問題なく動いている所をわざわざ書き換えてバグを作っているような気がするわな。

ところでリスト中にファイル名が存在するかを調べるのに

class CListBox(gtk.HBox):
    def __init__(self, window):
        self.sw = gtk.ScrolledWindow()
        self.view = gtk.TreeView()
        self.sw.add(self.view)
        self.liststore = gtk.ListStore(str)
        self.view.set_model(self.liststore)
        # etc...

    def is_text(self, text):
        # text in ListStore ?
        model = self.view.get_model()
        it = model.get_iter_first()
        while it:
            if model.get_value(it, 0) == text:
                return True
            it = model.iter_next(it)
        return False

こんな is_text というメソッドを作っていたのですが

def is_text(self, text):
    return text in [ r[0] for r in self.liststore ]

コレだけでイケたのね…
PyGtk って知れば知るほど親切な仕様だ。

とにかく書き換え箇所が多いので当面は自分でバグ探しになりそう。
ということでいつものようにバックアップ。
y901x-0.3.2b1.tar.gz

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 キー保管が簡単にできるディレクトリ名にしちゃうからね。

g_utf8_collate_key_for_filename of ctypes

g_utf8_collate_key_for_filename
がいったいどういう変換をしているかもう少し。

ところで端末に長々と打ち込むのが面倒なので GEdit 外部ツールに以下を指定。
GTK+ を使うには pkg-config 指定が必要なのよね、キーは F7 にした。

/*
gedit tool script

#!/bin/sh
gcc $GEDIT_CURRENT_DOCUMENT_PATH `pkg-config --cflags --libs gtk+-2.0`
*/

#include <stdio.h>
#include <gtk/gtk.h>
#include <glib.h>

int main() {
    gchar c[4];
    int i;
    for (i=0; i<105; i++) {
        sprintf(c, "%d", i);
        gchar *s = g_utf8_collate_key_for_filename (c, -1);
        printf("%s\n", s);
        g_free(s);
    }
    return 0;
}

端末だと解り難いにでリダイレクトしてみる。

十進で桁が増える毎にコロンが一つ付加されていくようだ。
なんだかよく解らない変換だけどこれで自然順ソート比較は上手くいくようだ。
色々やってみたけど結局 Python から ctypes を使う。

14.14.1 ctypesチュートリアル

ココに全部書いているんだが、Linux はちびっと面倒なのね。

glibc = ctypes.cdll.LoadLibrary('libglib-2.0.so.0')
cmpstr = glibc.g_utf8_collate_key_for_filename("a")

とやっても int が戻ってくる、実際にはポインタだが Python にはポインタ型が無いので。
つまり restype をキッチリ指定しないと全部 int になるってことですね。
ということで。

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

import ctypes

glibc = ctypes.cdll.LoadLibrary('libglib-2.0.so.0')
cmpstr = glibc.g_utf8_collate_key_for_filename
cmpstr.restype = ctypes.c_char_p
cmpstr.argtypes = [ctypes.c_char_p, ctypes.c_int]

def sort_nicely(l):
    l.sort(lambda x, y : cmp(cmpstr(x, -1), cmpstr(y, -1)))

たまには lambda を使ってみようと思ったので。
ガベージコレクションなのだからコレでいいはずだけど…
とにかくこれでどうだ?

よし Nautilus とはドットファイルを除けば一致するようになった。
隠しファイルはリストアップに含めないようにする予定なのでどうでもいいけど。

でも Mandriva KDE 上で動かしたら何故か数値ソートしてくれなかった。
って ./ を付け忘れで以前のバージョンを起動しただけだった、GNOME と同様になる。
つか Dolphin のソートって以前の関数とまったく同じ結果じゃん!

これじゃ設定でどちらかに振り分けしてもらうしか両対応の方法が無さそう。