974bdce47d
* tekuti/comment.scm: * tekuti/filters.scm: * tekuti/git.scm: * tekuti/post.scm: * tekuti/request.scm: * tekuti/util.scm: Update to use (tekuti match-bind).
148 lines
5.5 KiB
Scheme
148 lines
5.5 KiB
Scheme
;; Tekuti
|
|
;; Copyright (C) 2008, 2010 Andy Wingo <wingo at pobox dot com>
|
|
|
|
;; 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 3 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, contact:
|
|
;;
|
|
;; Free Software Foundation Voice: +1-617-542-5942
|
|
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
|
;; Boston, MA 02111-1307, USA gnu@gnu.org
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; Comments -- pulling them out of the database, and making new ones.
|
|
;;
|
|
;;; Code:
|
|
|
|
;;hack!
|
|
(define-module (tekuti comment)
|
|
#:use-module (tekuti git)
|
|
#:use-module (tekuti util)
|
|
#:use-module (tekuti filters)
|
|
#:use-module (srfi srfi-1)
|
|
#:use-module (srfi srfi-19)
|
|
#:use-module (sxml transform)
|
|
#:use-module (tekuti match-bind)
|
|
#:export (blob->comment comment-sxml-content comment-timestamp
|
|
comment-readable-date bad-new-comment-post? make-new-comment))
|
|
|
|
(define *comment-spec*
|
|
`((timestamp . ,string->number)))
|
|
|
|
(define (blob->comment encoded-name sha1)
|
|
(let ((blob (git "show" sha1)))
|
|
(match-bind
|
|
"\n\n(.*)$" blob (_ content)
|
|
(append
|
|
`((raw-content . ,content)
|
|
(sha1 . ,sha1)
|
|
(key . ,encoded-name))
|
|
(match-lines (substring blob 0 (- (string-length blob)
|
|
(string-length _)))
|
|
"^([^: ]+): +(.*)$" (_ k v)
|
|
(let* ((k (string->symbol k))
|
|
(parse (or (assq-ref *comment-spec* k) identity)))
|
|
(cons k (parse v))))))))
|
|
|
|
(define (comment-readable-date comment)
|
|
(let ((date (time-utc->date
|
|
(make-time time-utc 0 (assq-ref comment 'timestamp)))))
|
|
(date->string date "~e ~B ~Y ~l:~M ~p")))
|
|
|
|
(define (comment-raw-content comment)
|
|
(assq-ref comment 'raw-content))
|
|
|
|
(define (comment-sxml-content comment)
|
|
`(li (@ (class "alt") (id ,(assq-ref comment 'key)))
|
|
(cite ,(let ((url (assq-ref comment 'author_url))
|
|
(name (assq-ref comment 'author)))
|
|
(if (and url (not (string-null? url)))
|
|
`(a (@ (href ,url) (rel "external nofollow")) ,name)
|
|
name)))
|
|
" says:" (br)
|
|
(small (@ (class "commentmetadata"))
|
|
(a (@ (href ,(string-append "#" (assq-ref comment 'key))))
|
|
,(comment-readable-date comment)))
|
|
,(let ((format (or (assq-ref comment 'format) 'wordpress)))
|
|
((case format
|
|
((wordpress) wordpress->sxml)
|
|
(else (lambda (text) `(pre ,text))))
|
|
(comment-raw-content comment)))))
|
|
|
|
(define (comment-timestamp comment-alist)
|
|
(or (assq-ref comment-alist 'timestamp) #f))
|
|
|
|
(define (bad-email? x)
|
|
(if (emailish? x)
|
|
#f
|
|
`(p "Please pretend to specify a valid email address.")))
|
|
|
|
(define (bad-url? x)
|
|
(if (or (string-null? x) (urlish? x))
|
|
#f
|
|
`(p "Bad URL. (Only http and https are allowed.)")))
|
|
|
|
(define (bad-number? x)
|
|
(if (string->number x)
|
|
#f
|
|
'(p "Bad number. Give me something that Scheme's "
|
|
(tt "string->number") " will like.")))
|
|
|
|
(define *new-comment-spec*
|
|
`(("author" ,(lambda (x) #f))
|
|
("email" ,bad-email?)
|
|
("url" ,bad-url?)
|
|
("comment" ,bad-user-submitted-xhtml?)
|
|
("x" ,bad-number?)
|
|
("submit" ,(lambda (x) #f))))
|
|
|
|
(define (bad-new-comment-post? post-data)
|
|
(or (or-map (lambda (pair)
|
|
(and (not (assoc (car pair) *new-comment-spec*))
|
|
`(p "Bad post data: " ,(car pair))))
|
|
post-data)
|
|
(or-map (lambda (pair)
|
|
(and (not (assoc (car pair) post-data))
|
|
`(p "Incomplete post data:" ,(car pair))))
|
|
*new-comment-spec*)
|
|
(or-map (lambda (pair)
|
|
((cadr pair) (assoc-ref post-data (car pair))))
|
|
*new-comment-spec*)))
|
|
|
|
(define de-newline (s///g "[\n\r]" " "))
|
|
|
|
(define (make-new-comment key title post-data)
|
|
(let ((content (assoc-ref post-data "comment"))
|
|
(author (assoc-ref post-data "author"))
|
|
(email (assoc-ref post-data "email"))
|
|
(url (assoc-ref post-data "url")))
|
|
(let ((sha1 (with-output-to-blob
|
|
(for-each
|
|
(lambda (pair)
|
|
(format #t "~a: ~a\n" (car pair) (cdr pair)))
|
|
`((timestamp . ,(time-second (current-time)))
|
|
(author . ,(de-newline author))
|
|
(author_email . ,email)
|
|
(author_url . ,url)))
|
|
(display "\n")
|
|
(display content)))
|
|
(message (format #f "comment on \"~a\" by ~a" title author)))
|
|
(git-update-ref
|
|
"refs/heads/master"
|
|
(lambda (master)
|
|
(git-commit-tree (munge-tree1 master
|
|
'create
|
|
(list key "comments")
|
|
(list sha1 sha1 'blob))
|
|
master message #f))
|
|
5))))
|