Python」タグアーカイブ

GNOME notification area

clipoli の Linux 版を作ろうと思う。
GNOME でランチャなんて馬鹿馬鹿しいけどクリップボード機能は欲しいので。

Windows で言うタスクトレイは Linux では通知スペースと言うらしい。
ココにアイコンを表示させてランチャ形式にすればいいかな。

1月 ? 2011 ? ゴミ箱の中のメモ帳

方法は日本語でアッサリ見つかった。
GtkStatusIcon というのを作ってメニューを突っ込めばいいのね。

ini 読み込みコードは後で作るとして。
yield でタプルを戻すだけでいいから C# より簡単だ。

次にクリップボードとランチャの振り分け。
まあ実験段階なのでこんな感じで実験してみよう。

#! /usr/bin/python
# -*- encoding: utf-8 -*-

import pygtk
pygtk.require("2.0")
import gtk
import os

class TrayItem(gtk.Menu):
    def __init__( self, trayIcon):
        gtk.Menu.__init__( self)
        self.tray = trayIcon
        labels = [
            ("Launcher", "Totem", "totem"),
            ("Launcher", "Firefox", "firefox"),
            ("Launcher", "sasakima site", "xdg-open http://palepoli.skr.jp/"),
            ("Clipboard", "Clip", "てきすと") ]
        for l in labels:
            m = gtk.MenuItem(l[1])
            m.set_name(l[2])
            if l[0] == "Launcher":
                m.connect("activate", self.on_launcher)
            elif l[0] == "Clipboard":
                m.connect("activate", self.on_clipboard)
            self.append(m)
        self.append(gtk.SeparatorMenuItem())
        q = gtk.MenuItem("終了")
        q.connect("activate", self.on_quit)
        self.append(q)
        self.show_all()

    def on_launcher(self, widget):
        l = widget.get_name()
        os.system("%s &" % l)

    def on_clipboard(self, widget):
        c = gtk.Clipboard()
        c.set_text(widget.get_name())

    def on_quit(self, widget):
        gtk.main_quit()

    def show_menu(self, widget, button, time):
        self.popup( None, None, gtk.status_icon_position_menu, 0, time, self.tray)

    def show_menu_act(self, widget):
        self.popup( None, None, gtk.status_icon_position_menu, 0, 0, self.tray)

tray = gtk.StatusIcon()
trayMenu = TrayItem( tray)
tray.set_from_stock( gtk.STOCK_DIALOG_INFO)
tray.connect( "popup-menu", trayMenu.show_menu)
tray.connect( "activate", trayMenu.show_menu_act)
gtk.main()

GtkWidget も Name に文字列を突っ込むという無茶が可能なのね。
こんなことをしようと考えてしまうのは私くらいだろうけど。

.NET の Process.Start() みたく URL なら全自動ってならないや。
xdg-open に渡すしかないか、ちょっといまいちかも。
それとランチャはバックグラウンドで動かす用の & 指定も忘れずに。

gtk.status_icon_position_menu を指定すればこうなるのか。
None だと普通にカーソルがあった位置に出るんだよね。

えらく簡単にココまで作れてしまったなぁ。
やっぱり Linux のほうが何をするにも便利だよ。

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 はどうしよう、今日はもう寝るけど。

Using wget

結局 Windows に戻ったのは正月だけだった、あぁ Linux は快適。

Linux で不便なのは Opera 11 の検索バーで日本語変換を行うと死ぬことだけだ。
フォントは pre と monospace を VL ゴシックに変更しただけで綺麗になった。

一昔前では考えられないほどマトモ、新参の WebKit 軍団にボロ負けだったしね。
しかしデフォルトショートカットキーをコロコロ変更しないでよ。

ネットをウロウロしていると自作漫画配布サイトに。
最近は Blog 機能を利用しているせいか連番で落とせないトコばかり。
だったけど連番で一枚一枚配布している所もまだ存在するんだね。

これは久々に新規スクリプトを書かないと。
何のために wget コマンドが存在するというのか。
wget だけでリンクをたどるのではなく連番ファイル以外はいらないし。

連番最初は 0 か 1 だし確実に 100 ファイル以下だと決め付けでいいだろう。
パラメータ 2 つ指定を強制するけど自分で使うんだから問題無い。
一応ゼロ詰めしているかどうかで振り分けしている。

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

"""
    連番ファイルの一括ダウンロード
    
    コマンド
    $ download url num
    
    url 連番最初のファイルのフルパス
    num 最後のファイル番号の整数
"""

import sys
import os

if len(sys.argv) < 3:
    print "URL と 数を指定してください"
else:
    # ファイル名分離
    pathname, filename = os.path.split(sys.argv[1])
    try:
        n = filename.rindex(".")
    except ValueError:
        print "拡張子が見つかりません"
        sys.exit()
    # 連番最初の数値(0 or 1) と拡張子
    begin = int(filename[n-1])
    ext = filename[n:]
    # ゼロ詰めかどうかで振り分け
    if filename[n-2] == "0":
        name = "wget " + pathname + "/" + filename[:n-2] + "%02d" + ext
    else:
        name = "wget " + pathname + "/" + filename[:n-1] + "%d" + ext
    # 連番数のチェック
    try:
        end = int(sys.argv[2]) + 1
    except ValueError:
        print "二番目の引数は整数でお願いします"
        sys.exit()
    # 開始
    for i in range(begin, end):
        os.system(name % i)
        #print name % i

~/bin に download という名前で置いて chmod で +x して。
覚書ページに書いているけど ~/bin を作れば Ubuntu は勝手にパスが通る。

使ってみる、よしよし動く。
端末を普通に使うようになると「コレで十分」になって退化する私であった。
てゆーか、アッサリこんなのを作って使えるから Linux のほうが楽なんだよね。

実は Python での文字列のスライス方法を忘れていたので何か作ろうと…
こんなしょーもないスクリプトあたりをたまには作らないと忘れるねん。

関係無いけどこんなのを見つけた。

[ Dolphinで右クリックメニューを使う方法 Dolphin用Script] by ひねもすLinux

Dolphin でもスクリプト拡張ができるんだ、知らなかった。
しかし面倒くさいな、Nautilus がこうならないことを祈る。

Ubuntu 10.10 for DotNet EXE

こんなタイトルだけどまず Python の話。
Python で文字列を得ようとしたけど None が戻る場合がある。
今まで if で確認していたけど or 演算子が使えるようだ。

>>> import os
>>> print os.environ.get("HOME") or "Hentai"
/home/sasakima-nao
>>> print os.environ.get("LOLI")
None
>>> print os.environ.get("LOLI") or "Hentai"
Hentai

便利だけど他の言語と互換性が無いよな…
最近使っていないけど超何でもあり言語な C# なら同じ事が可能かな?
と思い久々に Ubuntu 10.10 で C# コードを書いてみたけどダメだった。

しかし何だこれは!

実行パーミッションが付いていたら exe を起動できるようになっている。
「./」指定をすると Tab キーで exe 拡張子までを保管する親切さだよ。
いつからだろう?Ubuntu 10.04 までは mono に渡す必要があったと思うんだけど。
Nautilus から W クリックすると書庫マネージャが起動してしまうんだけどw

てゆーか…
そんなに .NET アプリを Linux で使いたいのだろうか…

標準以外のライブラリは使わない、P/Invoke も WPF も利用しない。
であるならソレでもいいのだが、逆に Windows で GtkSharp なんかもご勘弁。
ところで Ubuntu 10.10 デフォルトは WindowsForm さえ使えないみたいですけど。

GtkSharp も TomBoy が残っている間は有るわけだが、今後はどうだか。
趣味プログラミングならともかくアプリケーション作りはライブラリ次第だもの。
小物を作るにも Python のほうが便利だしライブラリは標準で豊富だし、なんだよね。