Chaton > Archives > 2009/05/15

2009/05/15 07:35:00 UTCshiro
#
テスト
2009/05/15 07:42:40 UTC(び)
#
てすとっと
2009/05/15 07:43:30 UTCとおる@ファイヤーフォックス。
#
えーっとですね、APIでアクセスしたい人は、まず $room-url/apilogin というcgiにPOSTアクセスをかけてください。
ここなら$room-urlは http://practical-scheme.net/chaton/gauche ですね。
POSTで渡すパラメータはひとつ。'who' という名前で、そちらのクライアントプログラムの名前とかバージョンとか簡単に。
このcgiは返事にS式のalistを返します。
((post-uri . <post-uri>) (comet-uri . <comet-uri>) (cid . <cid>) (pos . <pos>))
順不同。後で項目が追加されるかも。
post-uriはpostするためのcgiのurl。comet-uriはlong pollするためのurl
cidはこのあとcomet-uriにGETするときに渡す値。
posは現在のログの最新位置で、現在の最新位置以降を取りたい場合はこの値をpの値として使ってください。最初のcometアクセスでアクティブログを全部取りたい場合はこの数値を無視してp=0を渡してください。
#
API まとめ。あー、スクロールになっちゃうのか。
2009/05/15 07:45:02 UTCnobsun
#
ううむ。やっぱり未読数でねなぁ。
#
firefox 3.0.10 on Ubuntu 9.04 on VMwareFusion
2009/05/15 07:48:05 UTC(び)
#
ばりばり出てます >Safari
#
タブ2つともちゃんと更新される
2009/05/15 07:48:45 UTCnobsun
#
今別のタブでは強酒部屋になってるけど。そちらのタブにも出ない
#
強酒→Gauche
2009/05/15 07:49:14 UTC(び)
#
それ、VMware上のFireFoxの別のタブ見てる時に未読が更新されないってことだよね?
2009/05/15 07:49:35 UTCnobsun
#
そそ
2009/05/15 07:49:43 UTC(び)
#
ふーむ
#
FireFoxで試してみればいいのかな
2009/05/15 07:50:12 UTCとおる@ファイヤーフォックス。
#
なぜかマウスイベントが発生しているとか。
2009/05/15 07:50:27 UTCshiro
#
マウスポインタが出て行くこと検知してポーリングをかけてるのが、VMWareでは妙なイベントになっているかも。
#
というか結構このマウスポインタのふるまいを把握しきれてなくて、今でもポインタがそのチャット部屋の画面にある時はポーリングを止めたいんだけど止まってなかったりするし。
2009/05/15 07:51:14 UTCnobsun
#
昨日のubuntu8.10では出てたんだけどなぁ。
2009/05/15 07:51:15 UTC(び)
#
FireFox起動
#
全く無問題だな
#
VMwareFusion縛りかしらUbuntu縛りかしら
2009/05/15 07:52:00 UTCshiro
#
エラーコンソールには何か出てる?
2009/05/15 07:52:05 UTC(び)
#
PowerPoint使ってる時にParallelsを起動する勇気はないなぁ...
2009/05/15 07:53:07 UTCnobsun
#
なにもでてない > エラーコンソール
2009/05/15 07:53:37 UTC(び)
#
おっと、今再現っぽいことに成功
2009/05/15 07:54:15 UTCえんどう
#
記念カキコ
2009/05/15 07:54:27 UTC(び)
#
chatonの部屋を開く→iframe内にマウスカーソル置く→Command+Tで新規タブ開く→カーソル動かさない→未読でない
2009/05/15 07:55:03 UTCnobsun
#
あれいま一瞬でた[1]
2009/05/15 07:55:23 UTC(び)
#
キーボードだけで新規タブ開いたり、タブ切り換えしてると出ないかも
2009/05/15 07:56:02 UTCshiro
#
フォーカスも見たほうがいいのかなあ (onblur, onfocus)。手元で実験してたときはフォーカスを見ても差が出なかったのでやめたんだけど
2009/05/15 07:56:12 UTCとおる@ファイヤーフォックス。
#
ほげ
2009/05/15 07:56:39 UTC(び)
#
FireFoxのWindowからマウスカーソル外したら未読が出るようになった
#
マウスカーソルを動かさずにCommand+Tabで他のアプリに切り替えている限りは、未読でない
2009/05/15 07:57:53 UTCshiro
#
onmouseoutが発動しないってことかな。
#
onblurの問題点は、iframeの中をクリックした時に外の人がフォーカスを取られたって思っちゃうことがあったんだよね、確か
2009/05/15 07:58:44 UTCnobsun
#
Chaton Gauche にいたときでてたけど
#
こちらにもどったら、
2009/05/15 07:58:56 UTCshiro
#
そんでiframeの中は別ドメインなので、「iframeの中にフォーカスがあたってるよ」ということを外に伝える手段が見つからなかった。
2009/05/15 07:59:04 UTCえんどう
#
long-pollって再帰じゃなく継続の方が良いのか?
2009/05/15 07:59:11 UTCnobsun
#
iframeに触らなくても消えた。
2009/05/15 07:59:53 UTCshiro
#
@えんどう javascriptならイベントハンドラとしてonsuccessなどが呼ばれるからそもそも再帰にならない
#
Schemeでアクセスしてるなら、普通にhttp-getの結果を待って処理して末尾再帰すればいい。
2009/05/15 08:00:31 UTCえんどう
#
了解っす
2009/05/15 08:01:06 UTCshiro
#
もちろんSchemeでも、いくつもコネクション張ってselectで待とう、なんて場合はイベントハンドラ呼び出しとおなじような状況になるので、継続渡しになる。
2009/05/15 08:01:14 UTCnobsun
#
テキストエリアに触れると消えるのか
2009/05/15 08:01:43 UTCshiro
#
つまるところ、ループの制御を明示的に外に渡すかどうかって違いかな。
2009/05/15 08:02:13 UTCとおる@ファイヤーフォックス。
#
curl `curl -F 'who=torubot' http://practical-scheme.net/chaton/chaton/apilogin | sed -n 's/^.*(comet-uri \. "\([^"]*\)").*(cid . \([0-9]*\)).*$/\1?cid=\2/p'`
#
ワンライナー。comet-uri にアクセスしても、発言内容はとれない?
2009/05/15 08:03:21 UTCshiro
#
pに数字渡してもらわないと。
#
あとcomet-uriに渡すcidのパラメータ名はcだ。
2009/05/15 08:03:50 UTCとおる@ファイヤーフォックス。
#
あ、なるほど。
2009/05/15 08:04:02 UTCshiro
#
/?c=<cid>&p=<pos>&t=<らんだむ> という感じ。
#
comet serverのリプライの方にもcache controlヘッダつけとこう。
2009/05/15 08:06:08 UTCとおる@ファイヤーフォックス。
#
sed って、& が元の行全体に置き換えられるんですね。初めて知った。
#
tesuto
2009/05/15 08:07:37 UTCnobsun
#
add-onを削除してやってみよう
2009/05/15 08:08:42 UTC(び)
#
noscriptがどのドメインかのスクリプトブロックしてたりしないかな?
2009/05/15 08:09:16 UTCとおる@ファイヤーフォックス。
#
もしかしたら、アクティブでないタブではバックグラウンドでスクリプトが走らない設定になってるとか。
#
xargs つかえばバッククォート使わなくてすむな。
2009/05/15 08:10:34 UTCnobsun
#
それどこの設定 > とおる
2009/05/15 08:11:11 UTCとおる@ファイヤーフォックス。
#
あーいや、もしかしたらそういう設定があるのかなぁと……。
2009/05/15 08:12:36 UTCnobsun
#
フォーカスの当ってないタブで書き換えが起こるようになった
2009/05/15 08:16:42 UTCとおる@ファイヤーフォックス。
#
テスト。
2009/05/15 08:18:34 UTCnobsun
#
ブラウザWindowを二つ開いて同じ部屋を表示してみる
#
これで片方からだけ書き込みするとどうなることが期待されてるんだろ。
#
フォーカスのない方のタイトルに未読数がでるのか
#
でiframeに触れなくても<body>内に触れると未読数表示が消えるのかな。やってみよっと
#
そのとおり。
#
てすと
#
てすと
2009/05/15 08:32:16 UTCnobsun
#
離席
2009/05/15 10:59:49 UTCえんどう
#
test
#
test
#
(use gauche.parameter)
(use rfc.http)
(use rfc.uri)
(use srfi-27)
(use text.tree)
(use util.list)

(define-class <chaton-config> ()
   ((client :init-keyword :client
	    :accessor client-of :init-value #f)
    (url    :init-keyword :url
 	    :accessor url-of :init-value #f)
    (login  :init-keyword :login
	    :accessor login-of :init-value #f)))

(define *chaton-config*
  (make-parameter
   (make <chaton-config> :client "TestChatonRader"
	 :url "http://practical-scheme.net/chaton/chaton"
	 :login "http://practical-scheme.net/chaton/chaton/apilogin")))

(define (make-mime alist)
  (let1 boundary (format "boundary-~a"
                         (number->string (* (random-integer (expt 2 64))
                                            (sys-time) (sys-getpid))
                                         36))
    (values (tree->string
             `(,(map (lambda (k&v)
                       `("\r\n--",boundary"\r\n"
                         "Content-disposition: form-data; name=\"",(car k&v)"\"\r\n\r\n"
                         ,(x->string (cdr k&v))))
                     alist)
               "\r\n--",boundary"--\r\n"))
            boundary)))

(define (POST room-url uri params)
  (receive (host path) (host&path uri)
    (receive (body boundary) (make-mime params)
      (receive (status hdrs body)
          (http-post host path body
                     :mime-version "1.0"
                     :content-type #`"multipart/form-data; boundary=,boundary")
        (unless (equal? status "200")
          (cerrf room-url "POST to ~a failed with ~a" uri status))
        (safe-parse room-url body)))))

(define (host&path uri)
  (receive (scheme specific) (uri-scheme&specific uri)
    (receive (host path q f) (uri-decompose-hierarchical specific)
      (values host path))))

(define (safe-parse room-url text)
  (guard (e [(<read-error> e)
             (cerrf room-url "invalid reply from server: ~s" reply)])
    ;;(print text)
    (read-from-string text)))

(define (cerrf room-url fmt . args)
  (apply errorf <chaton-error> :r
#
(use gauche.parameter)
(use rfc.http)
(use rfc.uri)
(use srfi-27)
(use text.tree)
(use util.list)

(define-class <chaton-config> ()
   ((client :init-keyword :client
	    :accessor client-of :init-value #f)
    (url    :init-keyword :url
 	    :accessor url-of :init-value #f)
    (login  :init-keyword :login
	    :accessor login-of :init-value #f)))

(define *chaton-config*
  (make-parameter
   (make <chaton-config> :client "TestChatonRader"
	 :url "http://practical-scheme.net/chaton/chaton"
	 :login "http://practical-scheme.net/chaton/chaton/apilogin")))

(define (make-mime alist)
  (let1 boundary (format "boundary-~a"
                         (number->string (* (random-integer (expt 2 64))
                                            (sys-time) (sys-getpid))
                                         36))
    (values (tree->string
             `(,(map (lambda (k&v)
                       `("\r\n--",boundary"\r\n"
                         "Content-disposition: form-data; name=\"",(car k&v)"\"\r\n\r\n"
                         ,(x->string (cdr k&v))))
                     alist)
               "\r\n--",boundary"--\r\n"))
            boundary)))

(define (POST room-url uri params)
  (receive (host path) (host&path uri)
    (receive (body boundary) (make-mime params)
      (receive (status hdrs body)
          (http-post host path body
                     :mime-version "1.0"
                     :content-type #`"multipart/form-data; boundary=,boundary")
        (unless (equal? status "200")
          (cerrf room-url "POST to ~a failed with ~a" uri status))
        (safe-parse room-url body)))))

(define (host&path uri)
  (receive (scheme specific) (uri-scheme&specific uri)
    (receive (host path q f) (uri-decompose-hierarchical specific)
      (values host path))))

(define (safe-parse room-url text)
  (guard (e [(<read-error> e)
             (cerrf room-url "invalid reply from server: ~s" reply)])
    ;;(print text)
    (read-from-string text)))

(define (cerrf room-url fmt . args)
  (apply errorf <chaton-error> :r
#
あれ?
#
長さ制限?
2009/05/15 11:04:08 UTCshiro
#
あっそうだ。
#
2kbだったかで制限してます。いま。
2009/05/15 11:04:24 UTCえんどう
#
(define-condition-type <chaton-error> <error>
  (room-url #f))

(define (fetch comet-uri pos cid)
  (receive (host path) (host&path comet-uri)
    (receive (code head body)
	(http-get host #`",|path|?t=,(sys-time)&p=,|pos|&c=,|cid|")
      body)))

(define (main args)
  (and-let* ((sx (POST (url-of (*chaton-config*))
			(login-of (*chaton-config*))
			(list (cons "who" (client-of (*chaton-config*))))))
	     (post-uri (assoc-ref sx 'post-uri))
	     (comet-uri (assoc-ref sx 'comet-uri))
	     (cid (assoc-ref sx 'cid))
	     (pos (assoc-ref sx 'pos)))
    (fetch comet-uri pos cid)))
#
$ gosh chaton-client.scm
*** SYSTEM-ERROR: read failed on #<iport (socket input #<socket (connect "66.33.214.68:9993")>) 0x77cab0>: Connection reset by peer
Stack Trace:
_______________________________________
  0  reader

  1  (rfc822-header->list remote)
        At line 278 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  2  (receive-header in)
        At line 224 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  3  (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ...
        [unknown location]
  4  (request-response request conn host request-uri request-body opts)
        At line 179 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  5  (http-get host (string-append "" (x->string path) "?t=" (x->string ...
        At line 67 of "./chaton-client.scm"
#
and-let*の先書いてなかった
#
test
2009/05/15 11:07:30 UTCshiro
#
cometサーバ再起動した
#
なんかおかしくなったらもう一度ためしてみて
2009/05/15 11:07:49 UTCえんどう
#
test
#
test
#
mainを実行すると待ち状態になり、ここにpostすると上記のエラーが出ます。
#
test
#
(define (fetch comet-uri pos cid)
  (receive (host path) (host&path comet-uri)
    (receive (code head body)
	(http-get #?=host #?=#`",|path|?s=1&t=,(sys-time)&p=,|pos|&c=,|cid|")
      body)))

(define (main args)
  (and-let* ((sx (POST (url-of (*chaton-config*))
			(login-of (*chaton-config*))
			(list (cons "who" (client-of (*chaton-config*))))))
	     (post-uri (assoc-ref sx 'post-uri))
	     (comet-uri (assoc-ref sx 'comet-uri))
	     (cid (assoc-ref sx 'cid))
	     (pos (assoc-ref sx 'pos)))
    (print (fetch comet-uri pos cid))))
#
$ gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?s=1&t=" (x->string (sys- ...
#?-    "/?s=1&t=1242385891&p=16840&c=155141783"
*** SYSTEM-ERROR: read failed on #<iport (socket input #<socket (connect "66.33.214.68:9993")>) 0x78f000>: Connection reset by peer
Stack Trace:
_______________________________________
  0  reader

  1  (rfc822-header->list remote)
        At line 278 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  2  (receive-header in)
        At line 224 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  3  (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ...
        [unknown location]
  4  (request-response request conn host request-uri request-body opts)
        At line 179 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  5  (http-get (debug-print host) (debug-print (string-append "" (x->st ...
        At line 67 of "./chaton-client.scm"
  6  (fetch comet-uri pos cid)
        At line 78 of "./chaton-client.scm"
2009/05/15 11:13:31 UTCshiro
#
接続が切れちゃってる?
#
確かにそっちのリクエストは来てるんだけど、
#
あ、それでちゃんとレスポンスも返してる。
#
うーん、cometからS式で返すのをテストしてないから何かおかしいかも。
#
s=1をつけないでやってみて。json形式で返るはず。
#
APIのドキュメントちょっと書いた。http://practical-scheme.net/chaton/doc?API
#
ドキュメント書くと色々プロトコルの欠陥が見えてくるな。
2009/05/15 11:20:42 UTCえんどう
#
$ gosh chaton-client.scm
*** CHATON-ERROR: POST to http://practical-scheme.net/chaton/chaton/apilogin failed with 500
Stack Trace:
_______________________________________
  0  (cerrf room-url "POST to ~a failed with ~a" uri status)
        At line 44 of "./chaton-client.scm"
  1  (POST (url-of (*chaton-config*)) (login-of (*chaton-config*)) (lis ...
        At line 71 of "./chaton-client.scm"
2009/05/15 11:20:53 UTCshiro
#
arererere
2009/05/15 11:21:11 UTCえんどう
#
これPOSTのときですね
#
てst
#
gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?t=" (x->string (sys-time ...
#?-    "/?t=1242386504&p=20092&c=208201887"
*** SYSTEM-ERROR: read failed on #<iport (socket input #<socket (connect "66.33.214.68:9993")>) 0x78f000>: Connection reset by peer
Stack Trace:
_______________________________________
  0  reader

  1  (rfc822-header->list remote)
        At line 278 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  2  (receive-header in)
        At line 224 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  3  (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ...
        [unknown location]
  4  (request-response request conn host request-uri request-body opts)
        At line 179 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  5  (http-get (debug-print host) (debug-print (string-append "" (x->st ...
        At line 67 of "./chaton-client.scm"
  6  (fetch comet-uri pos cid)
        At line 78 of "./chaton-client.scm"
#
なんだろ
2009/05/15 11:23:54 UTCshiro
#
あーapiloginがエラー吐いてる。ちょっとまって。
2009/05/15 11:24:24 UTCsaki
#
あ。すみません。変なアクセスしちゃったかも
2009/05/15 11:26:07 UTCえんどう
#
てす
2009/05/15 11:26:23 UTCshiro
#
んー、変なバージョンのapiloginがインストールされてたかな? もいっかい試してみて
2009/05/15 11:26:50 UTCえんどう
#
test
#
$ gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?t=" (x->string (sys-time ...
#?-    "/?t=1242386805&p=21792&c=98681268"
*** SYSTEM-ERROR: read failed on #<iport (socket input #<socket (connect "66.33.214.68:9993")>) 0x78f000>: Connection reset by peer
Stack Trace:
_______________________________________
  0  reader

  1  (rfc822-header->list remote)
        At line 278 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  2  (receive-header in)
        At line 224 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  3  (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ...
        [unknown location]
  4  (request-response request conn host request-uri request-body opts)
        At line 179 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  5  (http-get (debug-print host) (debug-print (string-append "" (x->st ...
        At line 67 of "./chaton-client.scm"
  6  (fetch comet-uri pos cid)
        At line 78 of "./chaton-client.scm"
#
同じですね
2009/05/15 11:28:15 UTCshiro
#
むむむむむ。あ、ちょっとまてよ。
#
いや、いいのか。ソケットへの出力をflushする前になんかしてるのかと思ったけどそんなことはなさそうだ。
#
gaucheのrfc.httpがおかしいのかな。
2009/05/15 11:29:48 UTCえんどう
#
?
2009/05/15 11:31:16 UTCshiro
#
ヘッダの終了を正しく検知できてないとか。
#
てすと
2009/05/15 11:31:47 UTCえんどう
#
test
#
$ gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?t=" (x->string (sys-time ...
#?-    "/?t=1242387083&p=23656&c=232710385"
*** SYSTEM-ERROR: read failed on #<iport (socket input #<socket (connect "66.33.214.68:9993")>) 0x10625a10>: Software caused connection abort
Stack Trace:
_______________________________________
  0  reader

  1  (rfc822-header->list remote)
        At line 278 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  2  (receive-header in)
        At line 224 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  3  (with-error-handler (lambda (e) (let ((e e)) (%guard-rec e e (else ...
        [unknown location]
  4  (request-response request conn host request-uri request-body opts)
        At line 179 of "/usr/local/share/gauche/0.8.14/lib/rfc/http.scm"
  5  (http-get (debug-print host) (debug-print (string-append "" (x->st ...
        At line 67 of "./chaton-client.scm"
  6  (fetch comet-uri pos cid)
        At line 78 of "./chaton-client.scm"
#
これはcygwinから。
2009/05/15 11:36:44 UTCshiro
#
test
#
test
#
こっちでも再現した
2009/05/15 11:38:48 UTCえんどう
#
http://dev.lshift.net/tonyg/json-scheme/json.ss
#
とりあえずこれ使うか
2009/05/15 11:40:13 UTCshiro
#
test
#
test
#
むむー。http-getの中で、ステータスラインを読んだあとヘッダを読みにいった時にconnection reset by peerを喰らってるんだな
#
ステータスラインは読めてるのに謎だ。
2009/05/15 11:46:35 UTCえんどう
#
http://practical-scheme.net/wiliki/wiliki.cgi?び%3Alog-2006
#
移植した人発見
#
404 Not Found

The given session key or entry name is wrong, or the session is expired.
#
失われた模様 orz
#
http://studio-te.com/Gauche-parser-0.1.tgz
2009/05/15 11:48:22 UTCshiro
#
g
#
今ひっかかってるのはjsonかS式か以前のhttpのところだから、
#
jsonが必要になるとは限らんよ
#
あ、apiloginも時々ランダムにfailするね。
2009/05/15 11:54:18 UTCshiro
#
もしかしてcomet server がちゃんとリクエストヘッダを全部読んでないのが原因かな
2009/05/15 11:56:01 UTCえんどう
#
ブラウザのときは問題ない?
2009/05/15 11:56:01 UTCshiro
#
test
#
あ、いけた。
2009/05/15 11:56:27 UTCえんどう
#
test
#
$ gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?t=" (x->string (sys-time ...
#?-    "/?t=1242388566&p=26975&c=49315108"
{"pos":27035,"nc":6,"ver":"kjod0a","cid":49315108,"text":"<div class=\"entry-header\"><span class=\"timestamp\">2009/05/15 04:56:27 PDT</span\n><span class=\"chatter\">えんどう</span\n></div\n><a class=\"permalink-anchor\" id=\"anchor-entry-4a0d586b-3a228\" href=\"http://practical-scheme.net/chaton/chaton/a/2009/05/15#entry-4a0d586b-3a228\" name=\"http://practical-scheme.net/chaton/chaton/a/2009/05/15#entry-4a0d586b-3a228\" target=\"_parent\">#</a\n><div class=\"entry-single\" id=\"entry-4a0d586b-3a228\"><span>test</span\n></div\n>"}
#
きたこれ
2009/05/15 11:56:46 UTCshiro
#
ブラウザの時はたまたま動いていたんだと思う。タイミング的に。
#
S式やってみて
#
z
2009/05/15 11:57:37 UTCえんどう
#
a
2009/05/15 11:57:53 UTCshiro
#
よっしゃ、うちからはできた。
2009/05/15 11:57:57 UTCえんどう
#
$ gosh chaton-client.scm
#?=host
#?-    "practical-scheme.net:9993"
#?=(string-append "" (x->string path) "?s=1&t=" (x->string (sys- ...
#?-    "/?s=1&t=1242388652&p=28212&c=186360003"
((pos . 28269) (nc . 7) (ver . "kjod0a") (cid . 186360003) (text ("えんどう" (1242388657 531412) "a")))
#
ktkr
#
textの構造は
2009/05/15 11:59:10 UTCshiro
#
(text <発言> <発言> ...)
#
<発言> : (<nick> (<seconds> <microseconds>) <line>)
2009/05/15 11:59:33 UTCえんどう
#
タイムスタンプか
2009/05/15 11:59:38 UTCshiro
#
secondsとmicrosecondsはタイムスタンプ
2009/05/15 12:00:28 UTCえんどう
#
このposとcidを引数に再帰すればよいですね
2009/05/15 12:00:40 UTCshiro
#
後から<発言>内の項目は増やすかも。permalinkとか。
#
そうです>再帰
#
ただ、現状、call前のposよりも返って来たposが小さかったらログがtruncateされたとみなす、という処理を入れる必要が。
#
でもそうすると前回からの差分がわからなくなるので、ここはプロトコルを直す必要あり。 (ブラウザではアクティブログを全部読み直してる)
2009/05/15 12:04:58 UTCえんどう
#
test
#
test2
#
test3
#
test3
#
test4
#
test5
#
test6
#
test7
#
a
#
b
#
c
#
(define (fetch comet-uri pos cid)
  (receive (host path) (host&path comet-uri)
    (receive (code head body)
	(http-get #?=host #?=#`",|path|?s=1&t=,(sys-time)&p=,|pos|&c=,|cid|")
      (let* ((sx (call-with-input-string body (cut read <>)))
	     (pos2 (assoc-ref sx 'pos))
	     (cid2 (assoc-ref sx 'cid))
	     (text (assoc-ref sx 'text)))
	(print text)
	(fetch comet-uri pos2 cid2)))))
#
えらーしょりしてないけど
2009/05/15 12:12:07 UTCshiro
#
今日は寝ます。
2009/05/15 12:15:18 UTCえんどう
#
おつかれさまでした
2009/05/15 12:21:11 UTCえんどう
#
test
#
test2
#
test3
#
test4
2009/05/15 12:30:49 UTCえんどう
#
test
#
test3
#
test4
#
いちおうできた
#
(use gauche.parameter)
(use gauche.process)
(use rfc.http)
(use rfc.uri)
(use srfi-27)
(use text.tree)
(use util.list)
(use util.match)

(define-class <chaton-config> ()
   ((client :init-keyword :client
	    :accessor client-of :init-value #f)
    (url    :init-keyword :url
 	    :accessor url-of :init-value #f)
    (login  :init-keyword :login
	    :accessor login-of :init-value #f)
    (npath   :init-keyword :npath
	     :accessor npath-of :init-value #f)
    (ipath   :init-keyword :ipath
	     :accessor ipath-of :init-value #f)))

(define *chaton-config*
  (make-parameter
   (make <chaton-config> :client "TestChatonRader"
	 :url "http://practical-scheme.net/chaton/chaton"
	 :login "http://practical-scheme.net/chaton/chaton/apilogin"
	 :npath "/usr/local/bin/growlnotify"
	 :ipath "/Users/yasuyuki/archives/chaton-room-gauche.gif")))

(define (make-mime alist)
  (let1 boundary (format "boundary-~a"
                         (number->string (* (random-integer (expt 2 64))
                                            (sys-time) (sys-getpid))
                                         36))
    (values (tree->string
             `(,(map (lambda (k&v)
                       `("\r\n--",boundary"\r\n"
                         "Content-disposition: form-data; name=\"",(car k&v)"\"\r\n\r\n"
                         ,(x->string (cdr k&v))))
                     alist)
               "\r\n--",boundary"--\r\n"))
            boundary)))

(define (POST room-url uri params)
  (receive (host path) (host&path uri)
    (receive (body boundary) (make-mime params)
      (receive (status hdrs body)
          (http-post host path body
                     :mime-version "1.0"
                     :content-type #`"multipart/form-data; boundary=,boundary")
        (unless (equal? status "200")
          (cerrf room-url "POST to ~a failed with ~a" uri status))
        (safe-parse room-url body)))))

(define (host&path uri)
  (receive (scheme specific) (uri-scheme&specific uri)
    (receive (host path q f) (uri-decompose-hierarchical specific
#
(define (safe-parse room-url text)
  (guard (e [(<read-error> e)
             (cerrf room-url "invalid reply from server: ~s" reply)])
    ;;(print text)
    (read-from-string text)))

(define (cerrf room-url fmt . args)
  (apply errorf <chaton-error> :room-url room-url fmt args))

(define-condition-type <chaton-error> <error>
  (room-url #f))

(define (send-notify config name body)
  (let ((client (client-of config))
	(npath (npath-of config))
	(ipath (ipath-of config)))
    (process-output->string
     (list npath "-i" ipath "-t" name "-m" body))))

(define (notify name body)
  (print "name=" name ", body=" body))

(define (fetch comet-uri pos cid)
  (receive (host path) (host&path comet-uri)
    (receive (code head body)
	(http-get host #`",|path|?s=1&t=,(sys-time)&p=,|pos|&c=,|cid|")
      (let* ((sx (call-with-input-string body (cut read <>)))
	     (pos2 (assoc-ref sx 'pos))
	     (cid2 (assoc-ref sx 'cid))
	     (text (assoc-ref sx 'text)))
	(match text [((name (sec mil) body)) (send-notify (*chaton-config*) name body)])
	(fetch comet-uri pos2 cid2)))))

(define (main args)
  (and-let* ((sx (POST (url-of (*chaton-config*))
			(login-of (*chaton-config*))
			(list (cons "who" (client-of (*chaton-config*))))))
	     (post-uri (assoc-ref sx 'post-uri))
	     (comet-uri (assoc-ref sx 'comet-uri))
	     (cid (assoc-ref sx 'cid))
	     (pos (assoc-ref sx 'pos)))
    (print (fetch comet-uri pos cid))))
#
あれ、preはだめかL
#
$ gosh chaton-client.scm
*** ERROR: : no matching clause for ()
Stack Trace:
_______________________________________
  0  (match:error text)
        [unknown location]
  1  (fetch comet-uri pos cid)
        At line 101 of "./chaton-client.scm"
#
いや、そんなことはない
#
どうだ
#
これでどう
#
うら
2009/05/15 12:40:30 UTCえんどう
#
t
#
1
#
2
#
1
#
2
#
3
#
4
#
5
#
7
#
7
#
9
#
a
#
b
#
d
#
e
#
a
#
b
#
c
#
d
2009/05/15 12:50:25 UTCえんどう
#
時々util.matchで落ちる
#
$ gosh chaton-rader.scm 
*** ERROR: : no matching clause for ()
Stack Trace:
_______________________________________
  0  (match:error text)
        [unknown location]
  1  (fetch comet-uri pos cid)
        At line 98 of "./chaton-rader.scm"
#
Lingr RaderはクリックしたときroomのURLを開く仕様だった。それをやるにはgrowlにcallbackを渡さなきゃならないんだけど、コマンドライン版のgrowlnotifyだと無理。
2009/05/15 12:59:42 UTCえんどう
#
http://practical-scheme.net/wiliki/wiliki.cgi?えんどう
#
とりあえず上記に貼っときました。
2009/05/15 19:12:04 UTCshiro
#
textのところは、エントリが複数入ってることもあるし、全く入ってないこともあります。
#
特にタイムアウトのping backでは()になってるので、上のエラーはそのせいでしょう。
2009/05/15 22:39:17 UTCshiro
#
クライアントライブラリつくってます
#
http://chaton.svn.sourceforge.net/viewvc/chaton/Chaton/trunk/client/
#
接続ごとにスレッドつくるのであんまりたくさん同時接続するのには向かないけど
#
そもそもそういう使いかたをしたらサーバの方が先に破綻するでしょう
2009/05/15 23:00:11 UTCえんどう
#
おお
2009/05/15 23:07:33 UTCえんどう
#
test
2009/05/15 23:07:41 UTCshiro
#
昨日貼った低レベルのPOSTやらなんちゃらは面倒みます。
2009/05/15 23:07:57 UTCえんどう
#
りょうかいです。
2009/05/15 23:08:10 UTCshiro
#
あとログイン処理やらpos/cidのところはえんどうさんの作ったのとかぶっちゃったけど、
#
たぶんどんなアプリでも似たようなものになるのでまとめた方がいいかなと。
#
chaton-connectに渡すobserverはcometサーバからのリプライで呼び出されます。
#
これは別スレッドで呼ばれるので、それでも良ければその中で処理をして#fを返す。
#
メインスレッドで処理をしたければ渡された引数をそのまま返せば、それが<chaton-client>ごとのメッセージキューに突っ込まれて
#
メインスレッドの方でchaton-message-dequeue!で読み出せます。
2009/05/15 23:10:40 UTCえんどう
#
りょうかいです。
#
なんかgrowlがとりこぼすなあ。growlのエラー処理とretryも入れないとだめかな。
2009/05/15 23:15:19 UTCえんどう
#
そういえば、http://practical-scheme.net/chaton/
#
のこのroomへのリンクをクリックするとgauche部屋に行っちゃうっぽいです
2009/05/15 23:21:10 UTCえんどう
#
てすと
#
もひとつ
#
$ /usr/local/bin/growlnotify -a "test" -t "test" -m "mes"
2009-05-16 08:23:55.913 growlnotify[3856:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
2009-05-16 08:23:55.917 growlnotify[3856:10b] Stack: (
    2499616939,
    2449456699,
    2499616395,
    2499616458,
    2520508681,
    2520507896,
    12843
)
Trace/BPT trap
#
growlが不安定なのか
2009/05/15 23:26:52 UTCshiro
#
りんく直した。まはろ。
2009/05/15 23:27:08 UTCえんどう
#
-aなしだとOK。
#
shiroさんのクライアントライブラリを使えば、ひとつのraderで複数の部屋を監視できますね
2009/05/15 23:28:44 UTCshiro
#
へい。複数の<chaton-client>を使うことは念頭に置いてます。
#
今irc bridge作ってます。ささださんとかにも来てほしいので。
2009/05/15 23:29:20 UTCえんどう
#
おお
#
ささだくんはrubyで書いちゃうかもですが
2009/05/15 23:30:29 UTCshiro
#
確かに。まあでもクライアントアプリのサンプルにもなるんで。