Programming」カテゴリーアーカイブ

IronPython 2.7

世間は震災情報に釘付け、当然私もそうであります。
私自身は愛知、親族は中国地方ばかりなので混乱はありませんでした。

そんな最中で IronPython 2.7 正式版が出たようです。
ただでさえ注目度が低い言語なのにタイミングが悪すぎる…

ironpython – Release: 2.7

どうやら 2.7 から .NET 4.0 専用になったみたい。
.NET 4.0 を導入していないと使えないので注意。

インストーラ版は一つしかないので 64bit では今回も (x86) ディレクトリに入る。

デフォルトでは 2.6 とは違う場所にインストールされた。
又しても環境変数の書き換えか、Windows はコレが面倒くさい。
2.6 が完全に残るので比較するには楽でいいのだけれど。

構成ファイルは結構違う。
chm ヘルプが同梱された、CPython に合わせたのだろうけど chm は古い…

IronPython.Wpf.dll とかは何だろう?
と思ったけど情報が見つからないのでテキトーに試した。

# -*- coding: UTF-8 -*-

import clr
import wpf # IronPython 2.7
"""
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")"""

from System.Windows import *
w = Window()
w.Title = "Titlebar"
w.Show()
a = Application()
a.Run(w)

reference 指定が import wpf だけでよくなった、簡単になって嬉しい。
他にも何か進歩があるだろうけど今はよくわからない。

2.6 には無かった gzip モジュールが有った。
残念ながら bz2 モジュールは無いみたいだがこれで tar.gz は展開できる。

2.7 互換なので collections.OrderedDict なんかも使える。

起動速度が 10% 早くなったらしい、もう少し早くならんかったのか…
たしかに 2.6 より起動は早いけど普段使うスクリプトには少しキビシイかも。

今のところこんだけ、ニュース見なきゃ。

gnomevfs to gio.File

GIO tutorial: File operations ? Johannes Sasongko’s blog

こんな Blog を見つけた。
そうか、こうやれば gio.File からファイルタイプが取得できるんだ。

これでやっと gnomevfs の呪縛から逃れられそうだ。
もうすぐというか GNOME 3.0 から使えなくなるはず。

PyGObject Reference Manual
gio Constants#gio-file-attribute-constants

上記を見れば名前空間は何を指定すればいいか解るね。
standard::type 指定だと GFileType が戻ってくるので standard::content-type かな。

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

import sys
import gio

s = sys.argv[1]
f = gio.File(s)
info = f.query_info("standard::content-type")

print "name: {0}\ntype: {1}".format(s, info.get_content_type())

おぉ、これで拡張子が無くても content_type が取得できる!
MIME Type とずっと書いていたけど content_type であったみたい…

沢山の info を query するにはコンマ区切りで書くかワイルドカードを使う。
ただしコンマの前後にスペースを入れると上手くいかないのは何故だろう。

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

import sys
import gio

s = sys.argv[1]
f = gio.File(s)

# Not Space
info = f.query_info("standard::type,standard::size,standard::content-type")
#info = f.query_info("*")

print info.get_file_type()
print info.get_size()
print info.get_content_type()

ついでに GStreamer から得られる uri も gio で変換できるようだ。

uri = self.player.get_property("uri")
#t = urllib.unquote(uri)[7:]
t = gio.File(uri).get_parse_name()

意図的に日本語ファイル名にしても問題なく変換できた。
というより gio.File() ってフルパスでも uri でもどっちでもいいんだね。
とにかくこれなら urllib モジュールもいらないな、gio スゲェ便利。

ということで Y901x 0.3.4 公開。

そうそう、0.3.3 で dbus を取っ払ったんで本体は gtk.Window 派生に変更した。
多重起動防止はなくなったけどやっと普通な PyGtk アプリになった感じ。
追加機能はほとんどやらずにこんなことばかりやっていていいものか…

wnck get_application

Ubuntu マシンを AMD 880G と Phenom II X4 955 に変更して一週間。
何もかも早くなったのは当然として終了に 10 秒掛からないのは衝撃である。

しかし Y901x が更に落ちやすくなった…
CPU が 4 コアになったからとしか思えない…

gtk.gdk.threads_init()

を呼ぶと落ちなくなるようだ、もう少し様子見。
マルチスレッドで動いている GStreamer をシングルスレッドで動かしていたから???

だけどコレを呼ぶと dbus による uri 転送でフリーズするんだなコレが。
これは uri 転送方法を変更するか、いっそ多重起動を許すか…
多重起動を許すのは簡単だ、多重起動防止処理を取っ払うだけだもの。

何か参考は無いかと /usr/bin を漁る。
少し違うけど gwibber のコードがおもしろい。

# Don't run again if we are already running
progname = "gwibber"
screen = wnck.screen_get_default()
while gtk.events_pending():
  gtk.main_iteration()
for w in screen.get_windows():
  if w.get_application().get_name() == progname:
    w.activate(int(time.time()))
    w.move_to_workspace(screen.get_active_workspace())
    quit()

そうか、今のワークスペースに移動って処理もあったほうがいいな。
ウインドウが移動するのではなくタスクバーに現れるのね、なるほど。

gwibber も Python 製だったのか。
インデントが滅茶苦茶だ、これでデフォルトアプリかよ…
ついでに、wnck を使うと WARNING が出るんだが…

get_application().get_name() と get_name() で違うんだね。
get_name() だけだとタイトルバー文字列になるんだけど。

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

import gtk
import wnck

screen = wnck.screen_get_default()
while gtk.events_pending():
    gtk.main_iteration()
for w in screen.get_windows():
    print w.get_application().get_name()
    print w.get_name()

さて Y901x はどうしよう、今日はもう寝るけど。

ubuntu C# matome

とりあえず Ubuntu での C# をまとめてみた。
Ubuntu で C# – L’Isola di Niente

-pkg 指定で pkg-config 展開ができるはずなんだが方法が見つからない。
MonoDevelop 使えで済ませようか、とも思うけどインストールするかどうかも迷っている。
というか見ての通りコッソリと Python を勧めているわけでw

とりあえずこんな感じで覚書ページを小分けで移植していこうと思う。

Clipoli 0.0.2

Clipoli で読み込む ini ファイルはどこに置くか。
exe と同じ位置では昔の古い考え方バリバリなアプリになってしまう。
やはり環境変数 %APPDATA% に置くべきだろう。

echo %APPDATA%

と cmd.exe で打てばそれが何なのか解らない人も理解できるだろう。
Opera や Firefox の設定もココにありますね。

ということで書いてみる。
C# では Environment を使わないと環境変数展開は無理みたい、まぁ ini 側はイケるだろう。
SeeMe の設定で sasakima というディレクトリを作るので同じ所に置くように。

string appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "sasakima");
if (!Directory.Exists(appdata))
{
	Directory.CreateDirectory(appdata);
}
appdata = Path.Combine(appdata, "clipoli");
if (!Directory.Exists(appdata))
{
	Directory.CreateDirectory(appdata);
}
appdata = Path.Combine(appdata, "default.ini");
if (!File.Exists(appdata))
{
	string s = "[Launcher]\r\ndefault.ini を開く=notepad %APPDATA%\\sasakima\\clipoli\\default.in";
	var sw = new StreamWriter(appdata);
	sw.Write(s);
	sw.Close();
}
var app = new TrayIcon(appdata);
Application.Run();

んでコンストラクタ引数に default.ini 位置を渡してコレを読み込むと。
こんな感じでいいかな、やってみる。

Process.Start じゃ環境変数の %APPDATA% を展開してくれない…

引数を半角スペースではなく別オーバーロード引数で渡さないと駄目みたい…

Linux に慣れすぎたのでコマンドラインと GUI の区別が付かなくなってしまった。
だって Linux はどちらも同じだもん、Windows では別物なんだよね。

えっと、%APPDATA% は自前で展開するしかないみたいなので Format するか。
コマンドを引数と分離するには、とりあえずファイル名に使えない | でも利用してみよう。

string appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "sasakima");
if (!Directory.Exists(appdata))
{
	Directory.CreateDirectory(appdata);
}
appdata = Path.Combine(appdata, "clipoli");
if (!Directory.Exists(appdata))
{
	Directory.CreateDirectory(appdata);
}
appdata = Path.Combine(appdata, "default.ini");
if (!File.Exists(appdata))
{
	string s = "[Launcher]\r\ndefault.ini を開く=notepad|{0}";
	s = string.Format(s, appdata);
	var sw = new StreamWriter(appdata);
	sw.Write(s);
	sw.Close();
}
var app = new TrayIcon(appdata);
Application.Run();

これで

private void on_launcher(object sender, EventArgs e)
{
	try
	{
		string s = (sender as ToolStripMenuItem).Name;// MessageBox.Show(s);
		int lPos = s.IndexOf('|');
		if (lPos == -1)
		{
			System.Diagnostics.Process.Start(s);
		}
		else
		{
			string name = s.Substring(0, lPos);
			string args = s.Substring(lPos + 1, s.Length - lPos - 1);
			System.Diagnostics.Process.Start(name, args);
		}
	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}

と分離して Process.Start する、意外に面倒な処理になっちまったなぁ。
後は多重起動防止させて、えっとそれから…
あぁアイコンを作る時間も無かった、つか十二時過ぎた、とりあえずバックアップ。

clipoli002.zip

今日は日経平均株価は上がってくれるだろうか…
木金で今月の稼ぎが吹っ飛んでもーたんだが…