Ubuntu」タグアーカイブ

Linux Trash GVfs

十月、Linux 関連は毎度のごとく半年に一度のバージョンアップ時期。
新しい環境を半年に一度楽しめる、何がどう進化したのか確認するのが楽しい。
グチャグチャになりかけた HDD 内データを整理するよい機会だから必ず別 HDD に新規インスコ。
その時点までの HDD バックアップができるオマケ付き、半年毎の OS 入れ替えはマジお勧め。
しかし…

GNOME 2.32 リリース・ノート

GNOME 3.0 で libgnomevfs が使えなくなるのをそろそろなんとかしなくては。
だって Y901x でしっかり利用しているんだもの。

ぱぇぽぃ2 ? Blog Archive ? Get MIME Type and Description

コレを使わずに MIME Type 取得か、どうやるのだ?
海外を探すと GObject や GIO を使えと出てくる。
色々探すと関係ないんだけど GVFS なんてものを見つけた。

GNOME には gvfs-trash なんてコマンドがあるのか。
もしかして…

$ gvfs-trash ファイル名

これでゴミ箱移動ができたのね…
トップページで公開している trash コマンドはどうしよう…

shell

シェル・スクリプトの基本

こんなページをチマチマ作っているけど自分で勉強になるわ。
本や既存サイトから情報を集めて元 Windows ソフト作者っぽく書き換えているので。
C-c とかいう書き方はどうしても馴染めない、てか今の Linux でソレはないと思うし。

標準エラー出力のリダイレクトは 2> と書くなんて今日まで知らなかった。
C シェルは書き方が違うが Ubuntu 使いなら B シェルだけでいいだろう。

それと気がついたんだけど ImageMagic が入っていた、9.10 には無かったのを確認。
最初からなのか何かのパッケージにくっついていたのかは解らないけど。

display
convert
identify
import
xv
netpbm

のコマンドも使える、結構おもしろい。

$ convert -sample 160x90 input.jpg output.jpg
$ identify input.jpg

しかし SyntaxHighlighter 3.0.83 が出ていたので変更しようと思ったのだが…

Opera のフォントは相変わらずだな…
というか Opera も Chrome もアルファベットの下が欠けてしまう!
駄目だこりゃ、v2 のまま当面は様子見するか。

いや、アクセス状況を見ると Blog よりまとめページに力を入れたほうが良さそうなので。
Blog は終わったとかよく見かけるけど今まで日本人は使い方を間違えていたのが正されてきただけ。
とにかく結果として情報のまとめページのほうが検索上位に、つーことだろう。

しかし IronPython のまとめは全然アクセスが無い、まったく無い。
どうがんばっても Windows でスクリプトは受け入れられそうにないな、と感じる。

SeeMe 5.0.1 and 1.0.5

GtkSharp TreeView Tutorial – Mono

まだ SeeMe for Linux を GTK# で作っていた頃の参考にしたトコ。
よく見ると自作クラスを型として GtkListStore を作成しているコードがあった。
Controlling how the model is used 以下のところね。

こういう型指定って PyGtk でもできるのかな?
可能であればもっと本体のコード量を減らすことができるんだが。
とりあえず Python で同じように SeeMe コードを書きかえてみた。

class Engine():
    def __init__(self, deleted=True, name="New Item", key="", url="", query="",
                post=False, endsp=False, encode="utf8", stype=0, pos=0,
                nameid=0, verb=0, icon="", unique="", usetld=0):
        self.delete = deleted
        self.name = name
        self.key = key
        self.url = url
        self.query = query
        self.post = post
        self.endsep = endsp
        self.encode = encode
        self.stype = stype
        self.pos = pos
        self.nameid = nameid
        self.verb = verb
        self.icon = icon
        self.unique = unique
        self.usetld = usetld

class SeeMe4(gtk.Window):
    def __init__(self, sset):
        gtk.Window.__init__(self)
        #...
        #self.default_liststore = gtk.ListStore(bool, str, str, str, str, bool, bool, str, int, int, int, int, str, str, int)
        self.custome_liststore = gtk.ListStore(Engine)

型指定の時点で駄目ジャン…
property にしてみたり小細工してみたりしたけど無駄な努力だった。
Python では変数宣言しただけでは型が決まっていないので当然なのかも。

gtk.ListStore

ま、公式の Constructor 解説には C 言語と同じ型を全部書く方法しか書かれていない。
できないことは素直に諦めて、せめて GtkListStore への append をもう少し簡単にやれないか?

てか、そうしておかないと後々のメンテで沢山書き換えを行わなければいけなくなる。
後で書き換えが必要だろう箇所が少なければ少ないほどミスが減るのよね。
というかソレがオブジェクト指向最大のメリットなのだし。

よく考えたら SeeMe で GtkListStore の型は一つしか無い。
だったら GtkListStore サブクラスを作ってコンストラクタでとっとと型を指定。
ついでに Engine クラスを受け取る add メソッドを作れば簡単になるかな?

class Engine():
    def __init__(self, deleted=True, name="New Item", key="", url="", query="",
                post=False, endsp=False, encode="utf8", stype=0, pos=0,
                nameid=0, verb=0, icon="", unique="", usetld=0):
        self.delete = deleted
        self.name = name
        self.key = key
        self.url = url
        self.query = query
        self.post = post
        self.endsep = endsp
        self.encode = encode
        self.stype = stype
        self.pos = pos
        self.nameid = nameid
        self.verb = verb
        self.icon = icon
        self.unique = unique
        self.usetld = usetld

class CreateListStore(gtk.ListStore):
    def __init__(self):
        gtk.ListStore.__init__(self, bool, str, str, str, str, bool, bool, str, int, int, int, int, str, str, int)

    def add(self, en):
        return self.append( [en.delete, en.name, en.key, en.url, en.query,
                en.post, en.endsep, en.encode, en.stype, en.pos,
                en.nameid, en.verb, en.icon, en.unique, en.usetld] )

class SeeMe4(gtk.Window):
    def __init__(self, sset):
        gtk.Window.__init__(self)
        #...
        self.custome_liststore = CreateListStore()
        #...

    def read_default_searchini(self):
        self.default_liststore.clear()
        inipath = self.sset.default_path
        lngpath = self.sset.lang_path
        if os.path.exists(inipath):
            ini = inifile8.Inifile(inipath)
            lng = inifile8.InifileReader(lngpath)
            try:
                self.iniver = ini.read_int("Version", "File Version", 0)
                i = 0
                while 1:
                    i += 1
                    s = "Search Engine %i" % i
                    if not ini.section_exists(s):
                        break
                    t = ini.read_str(s, "Key", "")
                    if t == "":
                        continue
                    en = Engine();
                    en.nameid = ini.read_int(s, "Nameid", 0);
                    if en.nameid != 0:
                        # Get View Name from *.lng
                        if en.nameid == 17171:
                            en.name = lng.read_str("Translation", "1632215285", "")
                        elif en.nameid == 17183:
                            en.name = lng.read_str("Translation", "-1971470391", "")
                        elif en.nameid == 71103:
                            en.name = lng.read_str("Translation", "-1453429782", "")
                        else:
                            en.name = lng.read_str("Translation", str(en.nameid), "")
                        if en.name == "":
                            n = -1752227277 - en.nameid;
                            en.name = lng.read_str("Translation", str(n), "")
                    else:
                        en.name = ini.read_str(s, "Name", "")
                    en.key = t
                    en.url = ini.read_str(s, "URL", "")
                    en.query = ini.read_str(s, "Query", "")
                    en.post = ini.read_bool(s, "Is post", False)
                    en.endsep = ini.read_bool(s, "Has endseparator", False)
                    en.encode = ini.read_str(s, "Encoding", "utf-8")
                    en.stype = ini.read_int(s, "Search Type", 0)
                    en.pos = ini.read_int(s, "Position", -1)
                    en.verb = ini.read_int(s, "Verbtext", 0)
                    en.delete = True #!
                    en.unique = ini.read_str(s, "UNIQUEID", "")
                    en.icon = ini.read_str(s, "ICON", "")
                    en.usetld = ini.read_int(s, "UseTLD", 0)
                    """self.default_liststore.append( [
                            en.delete, en.name, en.key, en.url, en.query,
                            en.post, en.endsep, en.encode, en.type, en.pos,
                            en.nameid, en.verb, en.icon, en.unique, en.usetld] )"""
                    self.default_liststore.add(en)

    def on_item_new(self, widget, event=None):
        uid = self.create_uuid()
        num = self.deditor.get_radio_num()
        if num == 2:
            num = -1988219522
        else:
            num = 0
        en = Engine(verb=num, unique= uid)
        #it = self.custome_liststore.append( [True, "", "", "", "", False, False, "utf-8", 0, -1, 0, num, "", uid, 0] )
        it = self.custome_liststore.add(en)

コードは全然短くならないけど Engine を直で渡して展開できるようになった。
デフォルト引数によってアトリビュートの型も大半が気にしないでいいという。
読み込みや新規アイテムで順番を気にする必要が無くなったのはデカい。
これなら後々で順番の入れ替えや追加の必要があっても型側で調節できる。

ただこのコードでは展開するために for ループにすると

for row in self.default_liststore:
    if row[0] == False:
        i += 1
        s = "Search Engine %i" % i
        ini.write_str(s, "UNIQUEID", row[13])

添字アクセスにするしか無いんだなぁこれが、意味ネェ。
イテレーターは整数による順番という概念を使わないことに意義があるのだが。
この部分については WPF は徹底的にやっている感じ、よく考えて作られているよ。
ここをアトリビュートで取り出すサブクラスをどうすれば作れるか考え中。

ということで重複キーチェック追加や不具合修正で Linux 版更新。
キーボードショートカットを増やしたり不具合修正で Windows 版も更新。

「こんなことができると楽」
な方法を考えている時がアプリケーション作りで一番楽しいです。

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 に限るね。