月別アーカイブ: 2013年4月

Xubuntu 13.04 and GtkApplication

Ubuntu 13.04 は少し軽くなったとはいえ相変わらず 3D しか使えない。
テスト用途にしか使わない仮想とはいえ重すぎる。
しかも操作性最悪、何故カスタマイズしてまで Unity を使う人がいるのか?

なので今回も LXDE…
では芸が無いので Xubuntu にしてみた、実は初めてです。

sudo apt-get install xubuntu-desktop

ってなんだこれ、ちっとも軽くないというより重すぎ!

XFCE は GTK2 ベースだけど 3D 表示しているんだな。
[ウインドウマネージャ(詳細)]で合成処理の有無を切り替えできるようだ。
ということは有効状態なら下記で背景が透けるはず。
Transparent GtkWindow | PaePoi

xubuntu_visual

off にすると Lubuntu ほどではない気がするけど充分軽くなった。
コレなら継続利用できそうだ、ということで気になる部分をチェック。

デフォルトプレイヤーの parole で動画が再生できないぞ!
しかしコイツもやはり GStreamer なのか。

xubuntu_video

gnome-session-properties に何も無い。
あれ?と思い 12.04 LTS のを見ても何もない、独自処理だったのか。
キーリングとかはどうしているんだろう、便利なのに。

ub_session

つまりディレクトリ名監視なんかしていない。
普通に不要なデフォルトディレクトリを削除したり F2 キーで変名できる。
何故かデスクトップだけは変名できなかったけど。

GTK+ のバージョンは 3.6.4 って今の Fedora と同じかい。
でも pygobject が変わっているのだからもしかして。

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

from gi.repository import Gtk, Gio
import sys

class Win(Gtk.Window):
    """
        Test "HANDLES_OPEN"
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        swin = Gtk.ScrolledWindow()
        self.view = Gtk.TextView()
        swin.add(self.view)
        self.add(swin)
        self.resize(320, 240)
        self.show_all()

    def add_uri(self, uris):
        buf = self.view.get_buffer()
        buf.set_text(uris)

class AppClass(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(
                self,
                application_id="org.gnome.test_id",
                flags=Gio.ApplicationFlags.HANDLES_OPEN )
        self.connect("startup", self.on_startup)
        self.connect("activate", self.on_activate)
        self.connect("open", self.on_open)

    def on_startup(self, data=None):
        self.window = Win()
        self.add_window(self.window)

    def on_activate(self, data=None):
        self.window.present()

    def on_open(self, application, files, n_file, hint, data=None):
        """
            Ubuntu 13.04 @ SUCSESS!
            Fedora 18    @ FAILED...
        """
        s = ""
        for f in files:
            s += "{0}\n".format(f.get_uri())
        if s == "":
            s = "FAILED..."
        self.window.add_uri(s)
        self.window.present()

if __name__ == "__main__":
    app = AppClass()
    app.run(sys.argv)

gtkapplication

ついに HANDLES_OPEN に対応してくれたようだ。
コレで多重起動防止アプリを Python で作るのが簡単になったね。
Fedora 19 が待ち遠しいぜ!

clipoli も動く、よしコイツはこのままでいいな。
memopoli も動く、いや初期状態に問題があることは解っているんだが。
とりあえず我がアプリは Y901x 以外は大丈夫であるようだ。

肝心の使い勝手は Lubuntu とたいして変わらない。
しかし標準テキストエディタはショボすぎだろ、GtkSourceView なのに。

Xubuntu は合成オフ可能なことに気がつくまではキレそうだったけど悪くない。
別に GTK2 ベースのデスクトップでも GTK3 開発は可能なわけだし。
ただ 3.6 なので Fedora 18 から乗り換える理由は何も無いけど。

FTP やスマホ接続で Nautilus が絶対にファイルマネージャである必要があるのでホスト OS は今後も GNOME にしますが。

There is no pygst in Ubuntu 13.04

Ubuntu 13.04 が出たので早速 Y901x の Gst 1.0 版をテスト。
の前にインストールしなきゃ、メインで使う気は無いので Boxes の仮想に。

日本語リミックスはまだ無いし今回も時代遅れの x86 のみかよ…
Amazon といい糞メニューバーといい、何故メインで使っている人がいるのか不思議だ。
x86 なんてイラネ、本家から x86_64 版の ISO を落とす。

インストール時に「サードパーティうんたら」のチェックを忘れずに。
GStreamer 関連は 1.0 と 0.10 が見えた、両方インストールされたみたい。

Boxes 仮想マシンにしたが 12.10 時と何も変わっていなかった。
設定 XML の tablet 項目を消して libvirtd プロセスを再起動しないとマウスホイールを認識しない。
仮想 3D でもチョッピリ軽くなった、本当にチョッピリだけど。

Amazon に関しては何も言うまい、一応私は dconf-editor で消した。
他相変わらず使い勝手が最悪だがテスト用仮想マシンだからどうでもいい。

あぁ GNOME アプリが本当に全部 3.6 になっている。
アプリケーションメニューにもしっかり対応したようだ。

nautilus3.6

3.6 ということは今ホストで使っている Fedora 18 と同じなわけで。
やっぱり新たに書くことが無いや。
Ubuntu しか知らない人は多分 Nautilus の変化にに面食らうと思うけど。

さて GStreamer について調べなきゃ。

girepo

やはり Fedora 18 同様に 1.0 と 0.10 が共存か。
「サードパーティうんたら」のチェックで m4v や flv も再生できた。
Totem や Nautilus は 3.6 なので GStreamer 1.0 を使っているはず。
しかし…

python_gst

pygst が無くなった!
もしかして Python3 側に、あるわけないか。
別途で入れられるとは思うけどこれではデフォルトでは Y901x 0.3.9 は動かない。

更に gst 1.0 対応作りかけ版を試すと再生できない…
URI からパス名への変換に GLib.filename_from_uri を使っているけど

filename_from_uri

おいおい、pygobject まで何か地味に変わっていやがる。
そこを別の方法で何とかしてみると…

opengl_error

OpenGL のエラーで音は出るけど映像は真っ暗という結果に。
仮想だからかとも思うけど Totem では普通に再生できるしワカラン。

もう嫌がらせとしか思えない、ヤル気なくしてきた。
まだ出たばかりだし単なる初期不具合だといいな、今はお手上げ。
という状態だけどバックアップ、Fedora 18 では動くんだけど。
y901x-0.99.3.tar.gz

File List in Numeric Order

よく見たら TreeView にファイルリスト配置までに物凄く無駄が多かった。
os.listdir でファイルリストを作成し更に隠しファイルを取っ払って新たに作成。
ディレクトリ名までリストに含めたソートを行い配置直前にディレクトリを弾く。

なんだこの非効率さは、実用上では問題ない速度とはいえ流石に書き換えたいわ。
当時は os.listdir 以外でファイルリストを作る手段を知らなかったわけで。

今なら Gio を利用して自力でファイルリストを作れる。
ディレクトリと隠しファイルを除き、数値優先ソートまで終わったリストを戻す関数を作ればいいかな。

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

from gi.repository import GLib, Gio

def get_file_numsort_list(dirname):
    """
        param dirname: Directory Full Path Name
        return: List in Numeric Order
    """
    files = []
    d = Gio.file_new_for_path(dirname)
    enum = d.enumerate_children(
            Gio.FILE_ATTRIBUTE_STANDARD_TYPE,
            Gio.FileQueryInfoFlags.NONE,
            None )
    for info in enum:
        if info.get_file_type() == Gio.FileType.REGULAR:
            s = info.get_name()
            if not s.startswith("."):
                if not s.endswith("~"):
                    files.append(s)
    files.sort(lambda x, y : cmp(GLib.utf8_collate_key_for_filename(x, -1), GLib.utf8_collate_key_for_filename(y, -1)))
    return files

イマイチな気もするけど予定していた動作にはなった。
G_FILE_TYPE_REGULAR 判定ならディレクトリではないと解る。
隠しファイルは自力判定、not を使うと or の動作がおかしかったので階層に。

体感速度は、全然変わらないなやっぱり。

それと。
Gstreamer の Volume 調節は何故か valadoc で見つけた。

Gst.Audio.stream_volume_convert_volume ? gstreamer-audio-1.0

Namespace: Gst.Audio ということだが Gst のアトリビュートには無い。
Python では GstAudio を gir から import すれば使えるようだ。

from gi.repository import Gtk, Gst, GstAudio

class Prayer(Gtk.Window):
    ###
    # etc...
    ###
    def set_volume(self, value):
        if self.player.get_volume(GstAudio.StreamVolumeFormat.CUBIC) != value:
            self.player.set_volume(GstAudio.StreamVolumeFormat.CUBIC, value)

    def on_volume_value_changed(self, widget, event=None):
        self.set_volume(widget.get_value() / 100.0)

get_volume, set_volume は引数に GstStreamVolumeFormat が必要。
PyGtk, gst-0.10 では LINEAR からの変換が必要だったけど直でイケる。

Vala も少し勉強していて良かった!
というか、こんなにドキュメントが充実しているなら Vala で作ったほうがいいのかな。

初回再生時に上下が少し潰れる現象で現在詰まっている。
一度リサイズすれば直るのだが、0.3.9 と同じ処理をしているのに。
GtkAspectFrame ではなく自力でアスペクト比と配置調節をしたほうがいいのかな?

他細々、ということでココまでのバックアップ。
現状では Fedora 18 で Gst デコーダーを揃えた環境しか動かせないけど。
y901x-0.99.1.tar.gz

追記 @ 2013.04.24
多分コレで日本語環境なら当面は問題無いと思う、けど次 Ubuntu 公開まで様子見しますんで。
もっと弄くりたいこともあるにはあるけどメジャー更新は安定させるのが最優先なので。
GTK3, GStreamer 1.0 環境以外は弾くようにしました。
y901x-0.99.2.tar.gz
追記終わり

ついでに。

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

from gi.repository import GLib

s = "/home/oyaji/エロ画像/乳.png"

# ディレクトリ名
print GLib.path_get_dirname(s)
# ファイル名のみ
print GLib.path_get_basename(s)
# 絶対パスチェック
print GLib.path_is_absolute(s)
# URI に変換
u = GLib.filename_to_uri(s, None)
print u
# パス名に戻す
print GLib.filename_from_uri(u, None)
# フルパス作成(区切り文字の有無を自動調節)
print GLib.build_filenamev(["/home/oyaji/", "/エロ画像", "尻.png"])

なんだ GLib で日本語ファイル名もイケるんだ、os.path は使わなくていいじゃないの。
特に os.path.join と同じように使える g_build_filenamev は素晴らしい。
日本人の Python 屋って標準モジュールで止まっている人が多すぎだから少し違ったことをすると通っぽく見えて素敵かもよ。

Ubuntu 13.04 gst

第270回 Ubuntu 13.04とGNOME:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社

どうやら Ubuntu 13.04 の Nautilus は 3.6 になるようだ。

ということは Ubuntu の GStreamer も 1.0 になるということだ!
Nautilus 3.6 は動画サムネイルに GStreamer 1.0 を使っている。

これは Y901x を早々に GStreamer 1.0 仕様に変更しなければ。
まだ 0.3.9 で動くからと PyGtk のまま放置のままもどうかと思うし。
作った本人、つまり筆者以外に使っている人はいないと思うけど。

Novacut/GStreamer1.0 – Ubuntu Wiki

大方はこのとおりに変更すればイケた。
playbin2 を playbin にするのを忘れないようにと。

しかし

playbin.get_property("uri") # All None

set_property(uri) は OK だが get は何をやっても None しか得られない。
既知のバグみたいなので修正を待つしかない、それまで別の手段で URI を保存しよう。

Gst.State.CHANGE_FAILURE に相当するものが見つからない。
PlayState 変更失敗はどうやって見分けるのだろう?

#self.p_position = self.player.query_position(gst.FORMAT_TIME)[0] # 0.10 PyGtk
self.p_position = self.player.query_position(Gst.Format.TIME)[1]  # 1.0 PyGI

ココでかなり苦しんだ、[0] だと bool 値だと気がつくのに時間が掛かった。
シークバーが全然動かなくて悩んだけどそういうことだった。

ボリューム変更の手段がいまだに解らない!
PyGst で gst.interfaces 以下の部分はどう変更になったのだろう?

で、
GStreamer とは関係ないところでも多々発見。

gtk.keysyms.Return が Gdk.KEY_Return と Gdk のアトリビュートになっていた。
gobject.timeout_add が GLib.timeout_add となったのも解り難い。

''' PyGtk
pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
color = gtk.gdk.Color()
blank_cursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)
'''
blank_cursor = Gdk.Cursor.new(Gdk.CursorType.BLANK_CURSOR)

透明マウスカーソルはこんなに簡単に作れるようになった、嬉しいぜ。
PyGtk でも実は同じような手段があったのかな?

何より一番困ったこと。

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

from gi.repository import Gtk, GdkPixbuf, Gdk

class CToolBox(Gtk.Box):
    """
        Inheritance GtkBox is HORIZONTAL
    """
    def __init__(self):
        Gtk.Box.__init__(self, Gtk.Orientation.VERTICAL, 0)
        self.pack_start(Gtk.Label("Orientation"), False, False, 0)
        self.pack_start(Gtk.Label("VERTICAL"), False, False, 0)

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect("delete-event", Gtk.main_quit)
        self.add(CToolBox())
        self.show_all()

Win()
Gtk.main()

vertical

これができないみたい。
GtkVBox から継承ならイケるんだけど、この場合は下記みたくするしか無いかな…

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

from gi.repository import Gtk, GdkPixbuf, Gdk

class CToolBox(Gtk.Box):
    """
        OK
    """
    def __init__(self):
        Gtk.Box.__init__(self)
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(Gtk.Label("Orientation"), False, False, 0)
        vbox.pack_start(Gtk.Label("VERTICAL"), False, False, 0)
        self.pack_start(vbox, True, True, 0)

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect("delete-event", Gtk.main_quit)
        self.add(CToolBox())
        self.show_all()

Win()
Gtk.main()

設定ダイアログは GtkTable を使っているので GtkGrid に書き換えだ。
面倒だから今度!

他にも何かあった気がするけど、気がついたら又今度書く。
とりあえずまだまともに動かないけど Blog にバックアップ。
もし明日筆者が死んでも誰かが続きをやってくれるのを期待して。
y901x-0.99.0.tar.gz

しかしやはり実際にアプリケーションを作ってみないと気がつかないことが多いと実感。
作った本人しか使わないと解っていても何か作り続けるといいことがある。

g_convert

最近の Gedit は Windows から持ってきた Shift-JIS のファイルを普通に読み込める。
ように思えますが実はチルダがバケる。

932

と秀丸で Shift-JIS 保存したものを Fedora に持ってくる。
ついでに iconv で CP932 及び SJIS 変換した例を下記に。

iconv

つまり Gedit は CP932 ではなく Shift-JIS から変換しているのですね。
Linux の持っていく場合は Windows 上で BOM 無し UTF-8 に変換しよう。
もし持ってきた後で気がついたら iconv で変換。

しかし天下の秀丸様でさえ CP932 を Shift-JIS なんて表記しているから困る。
Windows システムデフォルトのまま保存すると CP932 であるというのに。
この事実って Windows しか使えない人のほとんどが知らないという…

ということで。

Linux ユーザーにはお馴染みの iconv ですがプログラムから変換するにはどうする?
Python なら普通に文字コード変換関数があるけど Vala 等を使いたい時に困るので。

調べると、どうやら g_convert 関数で変換できるようだ。

Python

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

import sys
from gi.repository import GLib

try:
    result, contents = GLib.file_get_contents(sys.argv[1])
    if result:
        try:
            text, bytes_read, bytes_written = GLib.convert(contents, len(contents), "UTF-8", "CP932")
            print text
        except Exception, e:
            print "ConvertError: {0}".format(e)
except Exception, e:
    print "FileError: {0}".format(e)

Vala

using GLib;

public class Conv {
    public static int main(string[] args) {
        try {
            string contents;
            bool result = GLib.FileUtils.get_contents(args[1], out contents);
            if (result) {
                try {
                    string text = GLib.convert(contents, contents.length, "UTF-8", "CP932");
                    stdout.printf(text);
                } catch (GLib.ConvertError e) {
                    stdout.printf ("ConvertError: %s\n", e.message);
		            return 1;
                }
            }
        } catch (GLib.FileError e) {
		    stdout.printf ("FileError: %s\n", e.message);
		    return 1;
        }
        return 0;
    }
}

g_convert

こんな感じでいいみたい、Python でも Vala でも問題なく g_convert で変換できる。
Vala は例外処理を書かないとコンパイルで警告になるのが少し面倒だよね。
valadoc.org とニラメッコしなきゃ書けないよ。