SeeMe V5 001

SeeMe for Windows の Opera 10.60 対応版は IronPython で作ります。
一年前に途中まで作ってみたけど色々あってボツにした下記をベースで。

SeeMe is to IronPython

Linux しか使わなくなった作者が Windows のアプリを作るのは苦痛でしかない。
というより作者自身が使わないアプリを作ってもメンテナンスに疑問が残る。
こんな需要が少ないアプリを他の人がやってくれるとも思えない。
それより今の C# という言語が自分の趣味に合わない、Ruby が嫌いな理由と同じ。
ついでに VisualStudio を使いたくない、コンパイルもメンドクサイ。

一週間悩んだ結果、好き勝手にやることにした。
使いたい人は IronPython を導入してくれ、というトンデモネェ暴挙をマジでやる。

もちろんスクリプトのままで配る。
Windows しか使えない人の大半は EXE でないと拒否反応をするのは知っている。
それがキッカケで IronPython に興味を持ってくれる人が増えれば嬉しい。

戯言終わり、ということで。

xml:lang

現行の IronPyton では XAML に xml:lang=”ja-JP” を追記せずとも文字化けしない。
結局アレは IronPython のバグだったのだろうか?

WPF ListView DataBinding for IronPython

この pyevent.py をコピーさせなければいけないのもなんとかしたい。
ということでよく考えてみたらコレでいいのでは?と。

from System import *
from System.ComponentModel import *

# Search pyevent.py
import sys
tutorial_path = IO.Path.GetDirectoryName(sys.executable) + "\\Tutorial"
sys.path.insert(0, tutorial_path)
from pyevent import *

zip 版でも exe パス直下に Tutorial ディレクトリがあるのでイケるはず。
なんにせよ INotifyPropertyChanged は使わなければいけないわけで。
ただ zip 版を考えると os.path.join() は使えない…
追記 System.IO.Path.Combine() ってのがあった。

.NET Framework required BOM

この件もあった…
inifile8.py は他に os.path.exists を System.IO.File.Exists に書き換えて…
sys は組み込まれているけど他は Python 標準モジュールを使わないように…

SeeMe for Linux と共用できるコードがほとんど無いんだなコレが。

あとは x64 を見分けて Opera デフォルトインストール場所振り分けとか。
それから何があったかなぁ?もう少し更新が遅れるのはご了承。
とりあえず現在までのバックアップ。

seeme5_001.zip

少し楽しくなってきた、こんなことをやりながら作り上げていくのが楽しいんだよね。
「プログラミングを楽しむ」と「アプリを作って楽しむ」とでは実は少し違うのよ。

Mandriva 2010.1?

Mandriva Linux 2010.1 Finally Released – The Spring version of Mandriva Linux 2010 – Softpedia

http://fundawang.lcuc.org.cn/mandriva/official/iso/2010.1/

見つけたけど上記だと転送が 20KB/s くらい、日本の FTP サーバーに来るのを待つか。
ATI Radeon video driver 6.13 って X.Org 7.5 に対応しているのだろうか?
作りによっては Ubuntu から Mandriva One GNOME に戻るけど、どうなんだろう。
実際ココまでリリースが遅れると今後がかなり不安…

BlackBerry Ubuntu Connect

Ubuntu 10.04 を二ヶ月も利用していて今頃気がついた。
Rhythmbox も Totem もボリューム弄くったらまれに落っこちるじゃないの!

Y901x が落ちまくる原因が解らなくて困っていたんだが、そういうことか。
show event 吐いた時点で pulseaudio ボリューム調節しているんだもの。
相性問題なのか pulseaudio か GStreamer のバグなのか、これじゃお手上げ。

とにかく原因だけは解った、pulseaudio か GStreamer の更新を待つだけ。
自分でフロントエンドを作っていると同系アプリを使わないので気がつかなかった。

というか。
Linux をメインで使うようになって三年だが始めて Rhythmbox を使った。
BlackBerry に何故か音楽を入れたくなった、利用するかはやってみた後で考える。

BlackBerry 付属の USB コネクタでパソコンを繋げば普通に認識されるんだね。
ついでに USB 経由の充電も行われるようだ。

いや、「デジタル・オーディオ・プレイヤー」では無いんですけど…
microSD を差し込んでいるとソッチも認識される。

Windows でも試してみたけど同じように認識するようです。
いや普通なら Windows を基準に説明するだろ?はどうでもよくて。
とっとと手持ち CD をリッピング。

mp3 か aac でエンコードしたいんですけど…

編集ボタンを押すとこんなダイアログが出るけど出てこない…
試しに ogg でエンコードしてみたら

遅っ!

Windows の WMP で MP3 にエンコードしました、十倍以上早いんですけど。
やっぱり再生はともかくエンコードや編集は Windows に限るわ。

んで music というディレクトリにディレクトリごとコピーする。
アンマウントして USB コネクタを外しメディアプレイヤーを立ち上げる。
あっさり認識するけど .trash 内にあるファイルまで認識する、ちょっと迷惑。

よしよし、とにかくこれで BlackBerry に音楽が入れられた。

ついでに。
最近の YouTube FLV は普通に再生しても H.264 と AAC なんだね。
ちょっと前まで通常は H.263 と MP3 だったと思うんだけど。
これは簡単に見つかる ffmpeg コマンドで MP3 を抜く方法は使えないな。
AAC でいいなら

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

import os

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

path_array = os.environ["NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"].split("\n")
for f in path_array:
    pos = f.rindex(".")
    os.system(FFCOMMAND % (f, f[:pos]))

みたいなのを Nautilus スクリプトを登録して AAC を抜けばいい。
拡張子を aac にしないと上手くいかなかった、いや悪用厳禁で。
やってみたらそのまんま BlackBerry で再生できました。
こういうのは Linux に限るね。

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 のソートって以前の関数とまったく同じ結果じゃん!

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

utf8_collate_key

いいかげんに Y901x が落ちまくる件とソート問題を解決させねば。
なんとかさせないと追加機能もやれないよ。
落ちる件は色々試しているんだがまだ原因が解らない、困った…

ソートに関しては自力を諦め Nautilus のコードをひたすら追う。
libnautilus-private/nautilus-file.c
に compare_by_display_name というソレっぽい関数をやっと見つける。

display_name_collation_key を strcmp で比較しているだけなのか。
g_utf8_collate_key_for_filename という glib の関数で代入している。

Unicode Manipulation

あれ、もしかして数値もドットもこの関数一つで解決してまうの?

The Whole PyGTK FAQ

Python には実装されていないようで。
最近のバージョンではあるかもと dir() で探しまくるも見つからず。

とにかくこの関数でどう変換されるのか気になるので C でやってみる。
Ubuntu 10.04 デフォルトでは gcc はあるけど gtk や glib のヘッダは無い。
Glade を入れれば依存関係で Devhelp を含めまとめて入るので Glade を入れる。

/*
gcc  b.c `pkg-config --cflags --libs gtk+-2.0`
*/

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

int main() {
    gchar *c;
    c = "a1.mp4";
    gchar *u;
    u = g_utf8_collate_key_for_filename (c, -1);
    printf("%s to %s\n", c, u);
    /*g_free(c); is Segmentation fault*/
    g_free(u);
    return 0;
}

久々の C なんだがこんな感じでよかったかなぁ…
strcpy で警告になったのが Visual Studio と同じだったが代替が解らない。
とにかく結果。

なんだかよく解らないのに変換されとる。
後は比較関数を作って実験して上手くいったら…
Python で使うんだが、ctypes しか手が無いかな?