#! /usr/bin/guile \ -e main -s !# (use-modules (ice-9 exceptions)) (use-modules (srfi srfi-19)) (use-modules (sxml simple)) (use-modules (json)) (define guest-book-json-file "cgi-bin/guest_book.json") (define (decode-hex hex) (string (integer->char (string->number (string-append "#x" hex))))) ;; Handle query string encoding (define (format-query-string item) (letrec ((decode-query (lambda (value) (let ((index (string-index value #\%)) (value-length (string-length value))) (cond ((and index value-length) (string-append (substring value 0 index) (decode-hex (substring value (+ index 1) (+ index 3))) (cond ((< index (- value-length 3)) (decode-query (substring value (+ index 3) value-length))) (else "")))) (else value)))))) (decode-query (string-map (lambda (character) (case character ((#\+) #\space) (else character))) item)))) ;; Progress form data (define (get-form) (let ((query (getenv "QUERY_STRING"))) (cond ((string= query "") #f) (else (map (lambda (item) (let ((pairs (string-split item #\=))) (set-cdr! pairs (format-query-string (cadr pairs))) pairs)) (string-split query #\&)))))) (define (sanitize-input value) (let ((output (open-output-string)) (sanitized "")) (sxml->xml `(*TOP* ,value) output) (set! sanitized (get-output-string output)) (close-output-port output) sanitized)) (define (write-guest-to-json name url message) (let ((guest-book '()) (guest `(("name" . ,name) ("url" . ,url) ("message" . ,message) ("date" . ,(date->string (current-date) "~B, ~d ~Y"))))) (if (file-exists? guest-book-json-file) (call-with-input-file guest-book-json-file (lambda (fp) (set! guest-book (vector->list (json->scm fp))) ;; Handle order thingy (set! guest-book (map (lambda (item) (reverse item)) guest-book))))) ;; Guest already added. (letrec ((check-if-already-added (lambda (guests) (unless (eq? guests '()) (unless (letrec ((guest-item-compare (lambda (index) (if (< index (- (length guest) 1)) (and (cdr (list-ref (car guests) index)) (cdr (list-ref guest index)) (guest-item-compare (+ index 1))) ;; Unholyness (check-if-already-added (cdr guests)))))) (check-if-already-added guest-book)) ;; Add guest to guest-book (cond ((eq? guest-book '()) (set! guest-book (list guest))) (else (append! guest-book (list guest)))) ;; Write guest book to json (call-with-output-file guest-book-json-file (lambda (fp) (scm->json (list->vector guest-book) fp))))) (define (handle-fields) (let ((form (get-form))) (if form (let ((name (sanitize-input (cdr (list-ref form 0)))) (url (sanitize-input (cdr (list-ref form 1)))) (message (sanitize-input (cdr (list-ref form 2))))) (cond ((string= name "") ;; No name given (display "
name is required
")) ((string= message "") ;; No message given (display "please write a silly something (:
")) (else (write-guest-to-json name url message))))))) ;; Display a guest in the guest book (define (display-guest guest) (let ((date (cdr (list-ref guest 0))) (message (cdr (list-ref guest 1))) (url (cdr (list-ref guest 2))) (name (cdr (list-ref guest 3)))) (format #t "\n\ ~a ~a --- signed ~a\n\ |
\n\
~a \n\ |
\n\
Sign my fucking guest book\n\ \n\\n\ Be nice! Dont be a fucking ass.\n\ \n") (handle-fields) (display " | \n\
\n\
No guest have been added ): But you can be the first! \n\ |