#!/usr/bin/guile -s !# ; Dolda Connect - Modular multiuser Direct Connect-style client ; Copyright (C) 2007 Fredrik Tolf ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (use-modules (dolcon ui)) (use-modules (ice-9 pretty-print) (ice-9 rdelim)) (define fnetnodes '()) (define (make-getopt opts optdesc) (let ((arg opts) (curpos 0) (rest '())) (lambda () (if (eq? arg '()) rest (let ((ret #f)) (while (not ret) (if (= curpos 0) (if (eq? (string-ref (car arg) 0) #\-) (set! curpos 1) (begin (set! rest (append rest (list (car arg)))) (set! arg (cdr arg)) (if (eq? arg '()) (set! ret #t))))) (if (> curpos 0) (if (< curpos (string-length (car arg))) (begin (set! ret (string-ref (car arg) curpos)) (set! curpos (+ curpos 1))) (begin (set! curpos 0) (set! arg (cdr arg)) (if (eq? arg '()) (set! ret #t)))))) (if (eq? ret #t) rest (let ((opt (string-index optdesc ret))) (if (eq? opt #f) (throw 'illegal-option ret) (if (and (< opt (- (string-length optdesc) 1)) (eq? (string-ref optdesc (+ opt 1)) #\:)) (let ((ret (cons ret (let ((optarg (if (< curpos (string-length (car arg))) (substring (car arg) curpos) (begin (set! arg (cdr arg)) (if (eq? arg '()) (throw 'requires-argument ret)) (car arg))))) (set! arg (cdr arg)) optarg)))) (set! curpos 0) ret) (list ret)))))))))) (define (fn-getnames) (let ((resp (dc-ecmd "lsnodes")) (er #f)) (if (and resp (begin (set! er (dc-extract resp)) er) (= (cdr (assoc 'code er)) 200)) (let ((ires #f)) (while (begin (set! ires (dc-intresp resp)) ires) (if (assoc (car ires) fnetnodes) (set-cdr! (assoc (car ires) fnetnodes) (list-ref ires 5)) (set! fnetnodes (cons (cons (car ires) (list-ref ires 5)) fnetnodes)))))))) (define (fn-getname id) (if (not (assoc id fnetnodes)) (fn-getnames)) (if (assoc id fnetnodes) (cdr (assoc id fnetnodes)) (number->string id))) ;(define (fn-getname id) ; (let ((resp (dc-ecmd "lsnodes")) (er #f)) ; (if (and resp (begin (set! er (dc-extract resp)) er) (= (cdr (assoc 'code er)) 200)) ; (begin ; (catch 'found ; (lambda () ; (let ((ires #f)) ; (while (begin (set! ires (dc-intresp resp)) ires) ; (if (= (car ires) id) ; (throw 'found (caddr ires))) ; )) ; (number->string id) ; ) ; (lambda (key ret) ; ret))) ; (number->string id))) ; ) (define (chatlog-main args) (let ((dc-server #f) (log-dir #f) (last-fn #f)) (let ((getopt (make-getopt (cdr args) "hs:S:e:")) (arg #f)) (do ((arg (getopt) (getopt))) ((not (and (pair? arg) (char? (car arg)))) (set! args arg)) (cond ((eq? (car arg) #\h) (begin (display "usage: chatlog [-s server] [-d log-dir]\n" (current-error-port)) (display " chatlog -h\n" (current-error-port)) (exit 0))) ((eq? (car arg) #\s) (set! dc-server (cdr arg))) ((eq? (car arg) #\d) (set! log-dir (cdr arg))) ) ) ) (if (not log-dir) (set! log-dir (string-append (getenv "HOME") "/dc/chatlog"))) (dc-c&l #t dc-server #t) (dc-ecmd-assert 200 "notify" "fn:chat" "on" "fn:act" "on") (while #t (dc-select 10000) (while (let ((resp (dc-getresp))) (if resp (begin (let* ((er (dc-extract resp)) (code (cdr (assoc 'code er))) (cmd (cdr (assoc 'cmd er)))) (cond ((equal? cmd ".notify") (case code ((600) (let ((ires (list->vector (dc-intresp resp)))) (if ires (let ((p (open-file (string-append log-dir "/" (let ((fixedname (list->string (map (lambda (c) (if (eq? c #\/) #\_ c)) (string->list (fn-getname (vector-ref ires 0))))))) (if (= (string-length fixedname) 0) "noname" fixedname))) "a"))) (if (not (eq? (vector-ref ires 0) last-fn)) (begin (write-line (string-append " -- " (fn-getname (vector-ref ires 0)) ":")) (set! last-fn (vector-ref ires 0)))) (for-each (lambda (p) (write-line (string-append (strftime "%H:%M:%S" (localtime (current-time))) (if (eq? (vector-ref ires 1) 0) "!" ":") " <" (vector-ref ires 3) "> " (vector-ref ires 4)) p)) (list p (current-output-port))) (close-port p)) )) ) ; ((602) ; (let ((ires (dc-intresp resp))) ; (if ires ; (let ((ent (assoc (car ires) fnetnodes))) ; (if ent ; (set-cdr! ent (cadr ires)) ; (set! fnetnodes (cons (cons (car ires) (cadr ires)) fnetnodes))))))) ) ) ) ) #t) #f) ) #t ) ) ) ) (chatlog-main (command-line))