2009年12月28日月曜日

mac: Snow Leopard な NFS mount

Snow Leopard では NFS mount の指定方法がまた変わった。

ディスクユーティリティ: ファイル > NFS マウント

から指定する。これで最後かな。

mac: s/synergy/teleport/

2台目の MacBook を買ったので、久し振りに Synergy でも設定してみるかと 意気込んでみたものの、Snow Leopard でどうにも動かない。マウスは共有できるものの 、キーボードの入力が共有されない。 メンドクセーなーと調べていると、最近は teleport なるものが流行りらしい。

http://abyssoft.com/software/teleport/

うん、やりたかったことが全て解決。

  • 設定は GUI
  • クリップボードの共有
  • ファイルのドラッグ&ドロップ
  • 通信の暗号化

Mac - Win な共有はできないけど、Windows は VMware Fusion で済ませているので関係ない。

Mac OSX 10.6.2, teleport 1.0.2 で順調に動作しています。

2009年10月15日木曜日

trac: UI のカスタマイズ

trac の UI はイケてないと思うけど、これは見やすい。

https://opensvn.csie.org/traccgi/swlcu/

css パクったらできるかな

2009年8月17日月曜日

genshi: XML Template の仕様

genshi とはテンプレートエンジンの一つ。 trac の見栄えを変更する必要があって色々調べてたけど、なかなかてごわい。

で、調べたことをちょっとずつメモ。

<py:with="..."> ... とかの意味:

http://genshi.edgewall.org/wiki/Documentation/xml-templates.html

2009年7月24日金曜日

windows: プロダクトキーを取り出す

Wondows Product Key Vie http://www.rjlsoftware.com/software/utility/winproductkey/download.shtml

これで現状のプロダクトキーを表示できるそうな。

2009年7月22日水曜日

mac: leopard で WebDAV server

loepard には apache が付属していますが、httpd.conf を数行書き換えるだけで WebDAV server として動作します。便利っす。

edit /private/etc/apache2/httpd.conf (snip) # Include /private/etc/apache2/extra/httpd-dav.conf .... コメントインする。

/private/etc/apache2/extra/httpd-dav.conf を見て、 DavLockDB, uploads directory, password file を作る。

システム環境設定から apache を起動

2009年7月11日土曜日

cocoa: release と delete

実は release と delete の違いがよく分からなかったんだけど、実はどうってことなかった。

  • release はリファレンスカウンタを 1 減らす。リファレンスカウンタが 0 になったら delete を自動的に呼んでくれる
  • delete はリファレンスカウンタの値に関わらず解放する

2009年7月3日金曜日

misc: DejaGnu

http://en.wikipedia.org/wiki/DejaGnu

面白そう。ちょっと調べてみよう。

QMTest とかも見つけたけど、どうなんだろう?

http://www.codesourcery.com/qmtest

http://archives.free.net.ph/message/20061116.152652.ffd356bb.ja.html に 2 つを比較している話題があった。

2009年6月29日月曜日

2009年6月28日日曜日

python: バイトコンパイル

setup.py 使うほどでもないライブラリのインストール。

python -m py_compile hogelib.py

で、できた *.pyc を site-packages とかにコピー。

最適化は -O オプション。

2009年6月26日金曜日

blogger: syntax hilighter

インストールしなおしを繰り返していたら元に戻った! なんだったんだろう。まあ、いっか

2009年6月23日火曜日

misc: クラウドソーシング uTest

クラウド、という言葉は嫌いだけど、こういうアプローチは面白い。

http://www.utest.com/

クヌース先生の、tex のバグを見つけたら小切手、を大規模にしたようなもんか。

しかも割と成功しているみたい。日本でもサービスしてないのかな。

2009年6月18日木曜日

blogger: blogger syntax hilighter

syntax hilight ができなくなった。なんかしたっけかな?
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

testlink: teslink 語

testlink はドキュメントと UI がイケてないと思う。 なんかすごいらしいって聞いて、インストールしたまではいいけど、この後どうしようも なくなちゃうんじゃないかな。

で、とっつきにくさの原因の一つは、用語の定義が抽象的で分かりにくい、だと 思うので、windows を例にまとめてみた

テストプロジェクト Test Project
Windows 7 とか Windows vista とか Windows xp とか。以前はプロダクトという 名前だったらしい
テスト計画 Test Plan
月例パッチのリリースのタイミング (ちょっと無理があるか)
ビルド Build
ビルド番号。多くのチームではビルド毎に通し番号を付けている (と思う)

ここから質的に変わる。

テストケース Test Case
テストの最小単位
テストスイート Test Suite
テストケースの集合
テスト仕様 Test Specification
テスト仕様

2009年6月8日月曜日

cocoa: NSOutlineView

NSOutlineView で最低限実装しなければならないメソッドは4つ。

outlineView:numberOfChildrenOfItem:
item の下にぶらさがる 子item の数を返す。
outlineView:isItemExpandable:
子item のある/なし
outlineview:child:ofItem
子item を返す。index は 0 から始まり、numberOfChildren だけコールされる。
outlineView:objectValueForTableColumn:byItem:
item に対応する表示を返す。 ここを僕は勘違いしていて、item は識別子なんですね。item != 表示。
で、作ってみました。 なんとなく分かった気がする。
#import <cocoa.h>

@interface DataSource : NSObject {
    IBOutlet NSOutlineView *outlineView;
}

@end
#import "DataSource.h"

@implementation DataSource
// Data Source methods

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
NSLog(@"[numberOfChildrenOfItem] item:%@", item);
   return (item == nil) ? 2 : 2;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
NSLog(@"[isItemExpandable] item:%@", item);
    return ([item length] == 6) ? YES : NO;
}


- (id)outlineView:(NSOutlineView *)outlineView
  child:(int)index
    ofItem:(id)item
{
    NSLog(@"[child ofItem] index:%d item:%@", index, item);
    if (item == nil) {
        NSString *string = [[NSString alloc] initWithFormat:@"root-%d", index];
        return string;
    } else {
        NSString *string = [[NSString alloc] initWithFormat:@"%@-%d", item, index];
        return string;
    }
}

- (id)outlineView:(NSOutlineView *)outlineView
objectValueForTableColumn:(NSTableColumn *)tableColumn
    byItem:(id)item
{
     NSLog(@"[objectValueForTableColumnd]  item:%@", item);
     return (item == nil) ? @"/" : @"fuga/";
}

@end
Blogger Syntax Highliter は Objective-C に対応してないのね。がっくし。

cocoa: よく使う文字列操作

とりあえずこの 3 つをおさえておけば大丈夫そう。

連結
  • NSString *stringB = [stringA stringByAppendingString:@"hogehoge"];
  • NSString *stringC = [stringA stringByAppendingString:@"%d", 1];
比較
  • BOOL result = [stringA isEqualToString:@"hogehoge"];
  • BOOL result = [stringA hasPrefix:"ho"]; // startswith
  • BOOL result = [stringA hasSuffix:"ge"]; // endswith
長さ
  • unsigned int len = [string length]; // [@"ほげ" length] == 2

2009年6月6日土曜日

testlink: インストール

あまりにも testlink を持ち上げる人が多くて忌避していたんだけど、いろんな圧力に 負けて使ってみることにした。

で、testlinkjp.org の How to install がこれまたなえる内容だったので、 まとめなおしておこう。

  1. tar ball をゲット
  2. tar zxvf testlink*.tar.gz
  3. cp -r testlink /path/to/DocumentRoot/...
  1. httpd と mysqld を起動
  2. http://crassus.iij.ad.jp/testlink/install/index.php にアクセス
  3. あとは指示にしたがって適当に。

日本語化はユーザの管理からlocaleをjapanにすることで変更できた。

2009年5月30日土曜日

mac: Mail.app は VACUUM と REINDEX で速くなるらしい

Mail.app 2年ほど使ってたけど、どうにも遅くなってしまって、Thunderbird に乗り換えたのがつい先日。 キーバインドにどうしても慣れないけど、まあサクサク動くからいいやと思って使ってたけど、 そういやデータベースは sqlite 使ってるはずだから VACUUM とかで速くなるんじゃ? と思ったらやっぱり速くなるようだ。 http://blog.clouder.jp/archives/001110.html http://journal.mycom.co.jp/column/osx/236/index.html 会社へ行ったら早速やってみよう。 -- 追記 うむ。速くなった。

whitespace: ユーザからの入力をスタックに積む

$wspace cat.ws hogehoge # ユーザの入力 hogehoge # echo
こうゆうことがしたかったけど、Tutorial を読んでもよく分からんかった。 ようやく分かった。 heap に一旦置いて、heap から stack に積んであげる必要があるのね。
0をstackにpush (読み込みデータを置くheapのアドレス) Read a character or a number 0をstackにpush (読み込みデータを置いたheapのアドレス) heap から retrieve
これで入力されたデータが stack の一番上に積まれた状態になる。 直接 stack に積まれるもんだと思い込んでたから、理解するのに時間がかかった。

2009年5月16日土曜日

blogger API: blog を ChangeLogメモ のように使う

http://0xcc.net/unimag/1/ で ChangeLogメモを知ってからずっとChangeLogメモを愛用してきたのですが、
  • メモを入力できる場所が一つに限られる
  • 画像データを入力できない
  • 公開できない. そしてあわよくばアフィリエイトとかしてみたい
あたりが物足りなくなってきたので、今更ながらblogを使ってみることにしました。 コマンドラインからさくっと入力できるのがChangeLogメモの利点なので、これをgdata API で作ってみます。 先にオチを言っておくと検索がAPIで公開されてないんですね。残念。
class Blogger:

    def __init__(self, email, password):
        # Authenticate using ClientLogin.
        self.service = service.GDataService(email, password)
        self.service.source = 'blogger.py-1.0'
        self.service.service = 'blogger'
        self.service.account_type = 'GOOGLE'
        self.service.server = 'www.blogger.com'
        self.service.ProgrammaticLogin()

        # Get the blog ID for the first blog.
        feed = self.service.Get('/feeds/default/blogs')
        self_link = feed.entry[0].GetSelfLink()
        if self_link:
            self.blog_id = self_link.href.split('/')[-1]

    def createPost(self, title, content, author_name, label, is_draft=False):
        # Create the entry to insert.
        entry = gdata.GDataEntry()
        entry.author.append(atom.Author(atom.Name(text=author_name)))
        entry.title = atom.Title(title_type='html', text=title)
        entry.content = atom.Content(content_type='html', text=content)
        if label:
            entry.category.append(atom.Category(term=label,
                scheme="http://www.blogger.com/atom/ns#"))
        if is_draft:
            control = atom.Control()
            control.draft = atom.Draft(text='yes')
            entry.control = control

        # Ask the service to insert the new entry.
        return self.service.Post(entry,
            '/feeds/' + self.blog_id + '/posts/default')
ほとんど blogger api に付属のサンプルコードそのままなんですが、これを次のように使います。
from gdata import service
import gdata
import atom
import os
import re
import sys
from ConfigParser import SafeConfigParser
from optparse import OptionParser
from tempfile import NamedTemporaryFile

PasswdFile = os.path.join(os.environ.get('HOME'), '.password')

def sub_url(text):
    pattern = r'''
    \b
    (
     (https?|ftp):[\w/#~:.?+=&%@!\-]+?
    )
    (?=
     [.:?\-]*
     (?:[^\w/#~:.?+=&%@!\-] | $)
    )'''

    regex = re.compile(pattern, re.IGNORECASE|re.VERBOSE)
    result = regex.sub(r'\1', text)

    return result

def createBlogData():
    # edit temp blog data file 
    temp_file = NamedTemporaryFile(suffix='.txt', prefix='blogger_py')
    editor = os.environ.get('EDITOR')
    if editor == '':
        editor = 'vi' # XXX: default
    stat = os.spawnlp(os.P_WAIT, editor, editor, temp_file.name)
    if stat != 0:
        raise EditError, 'edit tempfile failed: %s %s' % (editor, temp_file.name)

    # read blog data from temp file, publish a public post.
    title = temp_file.readline().rstrip('\r\n')
    label = temp_file.readline().strip()
    if label == '':
        _title = title.split(':') # title == 'LABEL: string'
        if len(_title) >= 2:
            label = _title[0]
    content = temp_file.read()
    author_name = "zakkie3"

    content = sub_url(content)
    title = title.decode('euc-jp')
    content = content.decode('euc-jp')

    temp_file.close()  # temp_file will delete automatically

    return title, content, author_name, label

def main():
    email = ''
    password = ''
    author = ''

    # parse passord file
    cParser = SafeConfigParser()
    is_exists = cParser.read(PasswdFile)
    if is_exists and cParser.has_section('blogger.py'):
        if cParser.has_option('blogger.py', 'email'):
            email = cParser.get('blogger.py', 'email')
        if cParser.has_option('blogger.py', 'password'):
            password = cParser.get('blogger.py', 'password')
        if cParser.has_option('blogger.py', 'author'):
            author = cParser.get('blogger.py', 'author')

    # parse command-line options
    oParser = OptionParser()
    oParser.add_option("-e", "--email", dest="email", help="E-mail address");
    oParser.add_option("-p", "--password", dest="password",
        help="E-mail address");
    oParser.add_option("-u", "--author", dest="author",
        help="Blog author");
    oParser.set_description('follow options can be set by ~/.password.')

    option, args = oParser.parse_args()
    if option.email: email = option.email
    if option.password: password = option.password
    if option.author: author = option.author

    if email == '' or password == '' or author == '':
        oParser.print_help()
        sys.exit(2)

    blogger = Blogger(email, password)
    title, content, label = createBlogData()
    blogger.createPost(title, content, author, label)
~/.password に blogger のアカウント情報を以下のように書いておきます。
[blogger.py] email: EMAIL@example.com password: PASSWORD author: zakkie3
やっていることは
  • EDITORを起動し、temporary file を編集
  • temporary fileの1行目をtitle
  • 2行目をlabel, なければtitleの':'の前をlabel
  • 3行目移行を本文
  • 本文のうち、URLっぽい文字列はリンクにする
  • EUC-JP固定
もっとかっこいいやり方があるんだろうけど、自分用なのでこれで十分。

2009年5月12日火曜日

blogger: blogger api からラベルも設定

blogger api でラベルを設定する際にハマったのでメモメモ。
label = "hoge"
entry = gdata.GDataEntry()
entry.author.append(atom.Author(atom.Name(text=author_name)))
entry.title = atom.Title(title_type='html', text=title)
entry.content = atom.Content(content_type='html', text=content)
if label:
    entry.category.append(atom.Category(term=label,
        scheme="http://www.blogger.com/atom/ns#"))

2009年5月10日日曜日

mac: mac book で右クリック

Mac OS X では Ctrl-クリックで右クリック相当になるけど、 X11 では Ctrl-クリックが左クリックと判定されてしまう。 これ、MacBook で tgif 使ってハマりました。 トラックパッドの設定で2本指タップを右クリックにできて、これで回避できます。 いやーハマった。

2009年5月6日水曜日

cocoa: book review

最近これ読んでます。 和訳はないのですが、平易な英語で苦になりません。 asin:0321503619
Cocoa Programming for Mac OS X
単なる How-to の寄せ集めではなく、例えば Core Data がどのような要素から実現されているのか、といった背景の説明もあるので応用の幅も広がりそうです。 序文に曰く、"this book is just the resource you need. (snip) it does cover probably 80% of what you need to know." とのことで、実際なんかしらのアプリを作れそうな気になります。 Cocoa の入門書的な位置付けのようですが、"This book is written for programmers whi alredy know some C programming and something about objects" の言葉の通り、C とオブジェクト指向言語を知らないとチンブンカンブンだと思います。 -- 追記 errata 情報: http://www.bignerdranch.com/products.shtml

cocoa: NSBox で枠を表示しない

Attributes inspector で Display - transparent を ON にする。 巷の NSBox を使ってそうな、画面変更のあるアプリケーションでは枠とか当然のようになくて、どうやって実現しているんだろうって不思議だった。

2009年5月4日月曜日

diary: The GARDEN Oriental KYOTO

僕たちが結婚式を挙げた場所。 スタッフのみなさんの人柄もよく、建物や庭園の雰囲気も素敵です。 レストランもやっていて、ウエディング以外でも利用可能。 僕たちもまた行こう。 http://www.thegardenorientalkyoto.com/

2009年4月27日月曜日

cvs: merge, pullup

いまさらだけど、CVS の merge, pullup 方法についてまとめておく。 cvs diff -kk -c -r1.19 -r1.21 foo.c > patch patch < patch とするか、 cvs update -kk -j1.19 -j1.21 foo.c とする。2つは同等の結果をもたらす。 $Id$ とかで patch があたらなくなるが、-kk でこれを回避できる。 あとは diff を確認して、問題なければ commit する。 http://www.netbsd.org/ja/developers/releng/howto-pullup.html http://www.sodan.org/~penny/vc/cvs-ja_5.html

2009年4月22日水曜日

postfix: SMTP認証を使う (lenny編)

ハマった。 saslpasswd2 コマンドで認証DBが/etc/sasldbにできるが、debian のpostfixはchrootするため、これを参照できない。 cp -p /etc/sasldb /var/spool/postfix/etc とする必要がある。 以下のページが参考になった。 http://www.jp-z.jp/linux/postfix_tls.html

shell tool: find でファイルの属性を指定

-perm で指定する。 例: 全てに実行属性が付いているファイルを一覧する find . -name 'hoge*' -perm -111

2009年4月9日木曜日

iPhone: O'reilly の iPhone Hacks 本がタダで読める (Chapter 1のみ)

http://iphonehacks.oreilly.com/wiki

mac: nfs mount

Directory Utilityで "nfs://example.com/exports" "/Volume/hoge" の様に指定する。 resvport オプションが必要かもしれない。 resvport Use a reserved socket port number. This is useful for mounting servers that require clients to use a reserved port number on the mistaken belief that this makes NFS more secure. (For the rare case where the client has a trusted root account but untrustworthy users and the network cables are in secure areas this does help, but for normal desktop clients this does not apply.)

mew: imap でフォルダ一覧を更新する

3Z (大文字)

misc: 常駐型サーバーのデバッグ手法(ドラフト版)

WEB+DB Press に掲載された記事のドラフトのようで。 http://kzk9.net/publications/webdb48/debug.html

2009年4月7日火曜日

python, cocoa: C から python のコードを利用する

http://www.python.org/doc/2.2.3/ext/high-level-embedding.htmlを参考に。
#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}
- compile Leopard$ gcc -I/opt/local/include/python2.5 -L/opt/local/lib/python2.5/config -lpython2.5 -lm -lpthread -ldl -lutil -lreadline -ltermcap pytest.c -Wl,--export-dynamicが必要かも。 - run Leopard$ ./a.out Today is Tue Apr 7 01:25:52 2009

2009年4月2日木曜日

linux, embedded: MontaVista Linux の embedded community

http://meld.mvista.com/home.aspx

python: optparse: print_help

parse.print_help() で --help 相当が出力できる。いわゆる usage() をやりたいときに。

2009年4月1日水曜日

cocoa: 無料アイコン集

http://www.iconpot.com/

cocoa: Coca Programming Tips

http://homepage.mac.com/mkino2/cocoaProg/index.html

cocoa: Unit Test Flamework

ADC: http://developer.apple.com/tools/unittest.html 解説: http://homepage.mac.com/mindtools/OCUnit_J.html

blogger: コードのハイライト

Blogger Syntax Hibhlibhter 参考: http://www.kuribo.info/2008/06/blogger-syntax-highlighter.html

python: 元の文字コードを自動判別して utf-8 に変換

http://www.freia.jp/taka/blog/571 で見付けた
def guess_charset(data):
   f = lambda d, enc: d.decode(enc) and enc

   try: return f(data, 'utf-8')
   except: pass
   try: return f(data, 'shift-jis')
   except: pass
   try: return f(data, 'euc-jp')
   except: pass
   try: return f(data, 'iso2022-jp')
   except: pass
   return None

def conv(data):
   charset = guess_charset(data)
   u = data.decode(charset)
   return u.encode('utf-8')

python: loop counter

enumerate() を使うとループカウンタが簡単になる。
>>> a = [0,1,2,3]
>>> for i, value in enumerate(a):