1
0
Fork 0

atom feed maybe working

This commit is contained in:
Andy Wingo 2008-02-24 21:21:41 +01:00
parent 85b09abad7
commit caf9618312
7 changed files with 169 additions and 73 deletions

View file

@ -34,7 +34,7 @@
#:use-module (sxml transform) #:use-module (sxml transform)
#:use-module (match-bind) #:use-module (match-bind)
#:export (comment-from-object comment-sxml-content comment-timestamp build-comment-skeleton comment-readable-date #:export (comment-from-object comment-sxml-content comment-timestamp build-comment-skeleton comment-readable-date
bad-new-comment-post?)) bad-new-comment-post? make-new-comment))
(define *comment-spec* (define *comment-spec*
`((timestamp . ,string->number))) `((timestamp . ,string->number)))
@ -102,7 +102,7 @@
`(p "Please pretend to specify a valid email address."))) `(p "Please pretend to specify a valid email address.")))
(define (urlish? x) (define (urlish? x)
(match-bind "^https?://([a-zA-Z0-9-]+\\.)+[a-zA-Z]+/.*$" (match-bind "^https?://([a-zA-Z0-9-]+\\.)+[a-zA-Z]+/[a-zA-Z0-9$_.+!*'(),;/?:@&=-]*$"
x (_ . args) x (_ . args)
x x
#f)) #f))
@ -213,42 +213,44 @@
(if (not (assoc name dent-names)) (if (not (assoc name dent-names))
(error "file already removed" name))) (error "file already removed" name)))
names)) names))
(define (collect proc l) (let-values (((dents) (if treeish (git-ls-tree treeish #f) '()))
(reverse! (fold (lambda (x y)
(let ((foo (proc x)))
(if foo (cons foo y) y)))
'() l)))
(define (level-down x)
(cons (cdar x) (cdr x)))
(let-values (((dents) (git-ls-tree treeish #f))
((ladd dadd) (partition local? add)) ((ladd dadd) (partition local? add))
((lremove dremove) (partition local? remove)) ((lremove dremove) (partition local? remove))
((lchange dchange) (partition local? change))) ((lchange dchange) (partition local? change)))
(assert-added-files-not-present (map caadr ladd) dents) (assert-added-files-not-present (map cadr ladd) dents)
(assert-referenced-files-present (assert-referenced-files-present
(append (map cadr lremove) (map caadr lchange)) dents) (append (map cdr lremove) (map caar lchange)) dents)
(pk 'make-tree-deep treeish add remove change)
(make-tree (make-tree-full
(append (pk 'making (append
(map cdr ladd) (map cdr ladd)
(collect (filter-map
(lambda (dent) (lambda (dent)
(cond (cond
((member (car dent) (map cadr lremove)) ((member (car dent) (map cdr lremove))
#f) #f)
((member (car dent) (map caadr lchange)) ((member (car dent) (map cadr lchange))
(cadr lchange)) (cdr lchange))
((and (equal? (caddr dent) "tree") ((and (equal? (caddr dent) "tree")
(or (member (car dent) (member (car dent)
(map cadr (append dadd dremove dchange))))) (map caar (append dadd dremove dchange))))
`(,(car dent) (make-tree-deep (cadr dent) (pk 'hi! dent (map caar (append dadd dremove dchange)))
(map level-down dadd) (let ((level-down (lambda (x)
(map level-down dremove) (if (equal? (caar x) (car dent))
(map level-down dchange)) (cons (cdar x) (cdr x))
,(caddr dent) ,(cadddr dent))) #f))))
(else dent)))))))) (list (car dent)
(make-tree-deep (cadr dent)
(filter-map level-down dadd)
(filter-map level-down dremove)
(filter-map level-down dchange))
"tree" "040000")))
(else dent)))
(append (filter-map (lambda (x)
(and (not (assoc (caar x) dents))
(list x "tree" #f #f))
dadd))
dents)))))))
(define (mutate-tree master add remove change message) (define (mutate-tree master add remove change message)
(let ((tree (make-tree-deep master add remove change))) (let ((tree (make-tree-deep master add remove change)))
@ -256,9 +258,9 @@
(git* `("commit-tree" ,tree "-p" ,master) #:input message (git* `("commit-tree" ,tree "-p" ,master) #:input message
#:env '("GIT_COMMMITTER=tekuti"))))) #:env '("GIT_COMMMITTER=tekuti")))))
(define (update-master master proc) (define (update-master proc)
(let lp ((master master)) (let lp ((master (git-rev-parse "master")) (count 5))
(let ((commit (proc master)) (count 5)) (let ((commit (proc master)))
(cond (cond
((zero? count) ((zero? count)
(error "my god, we looped 5 times" commit)) (error "my god, we looped 5 times" commit))
@ -269,21 +271,31 @@
(pk "failed to update the master ref, trying again...") (pk "failed to update the master ref, trying again...")
(lp (git-rev-parse "master") (1- count))))))) (lp (git-rev-parse "master") (1- count)))))))
(define (make-new-comment post content) (define (make-new-comment post post-data)
(let ((content-sha1 (make-blob (let ((content (assoc-ref post-data "comment"))
(assoc-ref post-data "comment"))) (author (assoc-ref post-data "author"))
(metadata-sha1 (make-blob (with-output-to-string (email (assoc-ref post-data "email"))
(url (assoc-ref post-data "url")))
(let ((sha1 (create-blob
(with-output-to-string
(lambda () (lambda ()
(write ) (for-each
) (lambda (pair)
) metadata))) (format #t "~a: ~a\n" (car pair) (cdr pair)))
`((timestamp . ,(time-second (current-time)))
(author . ,(string-join
;; security foo
(string-split author #\newline)
" "))
(author_email . ,email)
(author_url . ,url)))
(display "\n")
(display content))))))
(update-master (update-master
master
(lambda (master) (lambda (master)
(mutate-tree master (mutate-tree master
`(((,(assq-ref post 'key) "comments" ,comment-key) `(((,(assq-ref post 'key) "comments") . (,sha1 ,sha1 "blob" "100644")))
("content" ,content-sha1 "blob" "100644"))
((,(assq-ref post 'key) "metadata" ,comment-key)
("metadata" ,metadata-sha1 "blob" "100644")))
'() '()
'()))))) '()
"new comment"))))))

View file

@ -27,7 +27,8 @@
(define-module (tekuti config) (define-module (tekuti config)
#:use-module (tekuti util) #:use-module (tekuti util)
#:export (*host* *port* *backlog* *git-dir* *git* *public-url-base* #:export (*host* *port* *backlog* *git-dir* *git* *public-url-base*
*private-url-base* *debug* *admin-user* *admin-pass*)) *private-url-base* *debug* *admin-user* *admin-pass*
*title* *name*))
(define *host* "127.0.0.1") (define *host* "127.0.0.1")
(define *port* 8081) (define *port* 8081)
@ -39,3 +40,6 @@
(define *debug* #t) (define *debug* #t)
(define *admin-user* "admin") (define *admin-user* "admin")
(define *admin-pass* "totingiini") (define *admin-pass* "totingiini")
(define *title* "My blog")
(define *subtitle* "Just a blog, ok")
(define *name* "Joe Schmo")

View file

@ -63,7 +63,7 @@
(string->list str)) (string->list str))
(display #\')))) (display #\'))))
(define *debug* #f) (define *debug* #t)
(define (trc . args) (define (trc . args)
(if *debug* (if *debug*
(apply pk args) (apply pk args)

View file

@ -69,8 +69,20 @@
(display "end\n" port)) (display "end\n" port))
(define (write-body request socket) (define (write-body request socket)
(display (rref request 'doctype "") socket) (let ((sxml (rref request 'sxml #f)))
(sxml->xml (rref request 'sxml '()) socket)) (if sxml
(begin (display (rref request 'doctype "") socket)
(sxml->xml sxml socket))
(display "" socket))))
(define (request-output-headers request)
(let ((rheads '(("Content-Type" . output-type))))
(map (lambda (h)
(cons (car h)
(or (and=> (assoc-ref (car h) rheads)
(lambda (k) (rref request k #f)))
(cdr h))))
(rref request 'output-headers '()))))
(define (connection-received socket sockaddr index) (define (connection-received socket sockaddr index)
(let* ((headers (pk (read-headers socket))) (let* ((headers (pk (read-headers socket)))
@ -84,7 +96,7 @@
(let ((res (handle-request (make-request 'headers headers (let ((res (handle-request (make-request 'headers headers
'post-data post-data) 'post-data post-data)
index))) index)))
(write-headers (rref res 'output-headers '()) socket) (write-headers (request-output-headers res) socket)
(write-body res socket))) (write-body res socket)))
(lambda args (lambda args
(write-headers '(("Status" . "500 Internal Server Error") (write-headers '(("Status" . "500 Internal Server Error")

View file

@ -51,11 +51,16 @@
page-debug page-debug
page-search page-search
page-show-post page-show-post
page-feed-atom
page-feed-rss2
page-debug page-debug
page-not-found)) page-not-found))
(define (relurl path . body) (define (relurl path)
`(a (@ (href ,(string-append *public-url-base* path))) (string-append *public-url-base* path))
(define (rellink path . body)
`(a (@ (href ,(relurl path)))
,@body)) ,@body))
(define (make-post-key . parts) (define (make-post-key . parts)
@ -107,7 +112,7 @@
(assq-ref index 'posts) (assq-ref index 'posts)
n)) n))
(rcons* request (rcons* request
'body `(,(sidebar-ul `((li (h2 ,(relurl "admin/posts" "posts")) 'body `(,(sidebar-ul `((li (h2 ,(rellink "admin/posts" "posts"))
(ul ,@(post-links 10))) (ul ,@(post-links 10)))
(li (h2 "recent comments") (li (h2 "recent comments")
(p "ain't got none")))) (p "ain't got none"))))
@ -115,12 +120,12 @@
,(post-editing-form #f)))))) ,(post-editing-form #f))))))
(define (admin-post-link post) (define (admin-post-link post)
(relurl (string-append "admin/posts/" (rellink (string-append "admin/posts/"
(url:encode (assq-ref post 'key))) (url:encode (assq-ref post 'key)))
(assq-ref post 'title))) (assq-ref post 'title)))
(define (post-link post) (define (post-link post)
(relurl (string-append "archives/" (url:decode (assq-ref post 'key))) (rellink (string-append "archives/" (url:decode (assq-ref post 'key)))
(assq-ref post 'title))) (assq-ref post 'title)))
(define (page-admin-posts request index) (define (page-admin-posts request index)
@ -130,7 +135,7 @@
(define (post-headers) (define (post-headers)
(map (lambda (post) (map (lambda (post)
;; double-encoding is a hack to trick apache ;; double-encoding is a hack to trick apache
`(h3 ,(relurl (string-append "admin/posts/" (url:encode (assq-ref post 'key))) `(h3 ,(rellink (string-append "admin/posts/" (url:encode (assq-ref post 'key)))
(assq-ref post 'title)))) (assq-ref post 'title))))
(assq-ref index 'posts))) (assq-ref index 'posts)))
(rcons* request (rcons* request
@ -262,8 +267,9 @@
(rcons* request (rcons* request
'body `((p "Bad post data: " ,reason))))) 'body `((p "Bad post data: " ,reason)))))
(else (else
(let ((comment (make-new-comment (post-from-tree slug tree) data)))
(rcons* request (rcons* request
'body `((p "hey hey hey like fat albert"))))))) 'body `((p "hey hey hey like fat albert" ,comment))))))))
(else (else
(page-not-found request index))))) (page-not-found request index)))))
@ -356,3 +362,59 @@
'status 404 'status 404
'body `((h1 "Page not found") 'body `((h1 "Page not found")
(p "Unknown path: " ,(rref request 'path-str))))) (p "Unknown path: " ,(rref request 'path-str)))))
(define (page-feed-rss2 request index)
(not-implemented request index))
(define (rfc822-date->timestamp str)
(+ (time-second (date->time-utc
(string->date str "~a, ~d ~b ~Y ~H:~M:~S GMT")))
(date-zone-offset (current-date))))
(define (timestamp->atom-date timestamp)
(date->string (time-utc->date (make-time time-utc 0 timestamp) 0)
"~Y-~m-~dT~H:~M:~SZ"))
(define (page-feed-atom request index)
(let ((last-modified (let ((posts (assq-ref index 'posts)))
(and (pair? posts)
(assq-ref (car posts) 'timestamp)))))
(cond
((let ((since (assoc-ref (rref request 'headers '())
"If-Modified-Since")))
(and since (>= (rfc822-date->timestamp since) last-modified)))
(rcons* request
'status 304
'doctype #f))
(else
(rcons* request
'doctype ""
'output-type "application/atom+xml"
'sxml `(feed
(@ (xmlns "http://www.w3.org/2005/Atom")
(xml:base ,(relurl "feed/atom")))
(title (@ (type "text")) ,*title*)
(subtitle (@ (type "text")) ,*subtitle*)
(updated ,(timestamp->atom-date last-modified))
(generator (@ (uri "http://wingolog.org/software/tekuti")
(version "what"))
"tekuti")
(link (@ (rel "alternate") (type "text/html")
(href ,(relurl ""))))
(id ,(relurl "feed/atom"))
(link (@ (rel "self") (type "application/atom+xml")
(href ,(relurl "feed/atom"))))
,@(map
(lambda (post)
`(entry
(author (name ,*name*) (uri ,(relurl "")))
(title (@ (type "text")) ,(assq-ref post 'title))
(id ,(assq-ref post 'key))
(published ,(timestamp->atom-date
(assq-ref post 'timestamp)))
(content (@ (type "xhtml")
(xmlns "http://www.w3.org/1999/xhtml"))
(div ,(post-sxml-content post)))))
(take-max (assq-ref index 'posts) 10))))))))

View file

@ -166,7 +166,7 @@
,(comment-form post "" "" "" "")))))) ,(comment-form post "" "" "" ""))))))
(define (post-n-comments post) (define (post-n-comments post)
(length (git-ls-subdirs (assq-ref post 'sha1) "comments/"))) (length (git-ls-subdirs (string-append (assq-ref post 'sha1) ":comments") #f)))
(define (post-sxml-n-comments post) (define (post-sxml-n-comments post)
`(div (@ (class "feedback")) `(div (@ (class "feedback"))

View file

@ -38,6 +38,7 @@
(define *status-names* (define *status-names*
'((200 . "OK") '((200 . "OK")
(201 . "Created") (201 . "Created")
(304 . "Not Modified")
(401 . "Unauthorized") (401 . "Unauthorized")
(404 . "Not Found") (404 . "Not Found")
(500 . "Internal Server Error"))) (500 . "Internal Server Error")))
@ -51,6 +52,7 @@
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n")) "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"))
;; what the hell is this
(define (request-output-headers request) (define (request-output-headers request)
(let-request request ((output-headers '()) (let-request request ((output-headers '())
(status 200) (status 200)
@ -73,9 +75,10 @@
(define (finalize request) (define (finalize request)
;; update output headers ;; update output headers
;; templatize body ;; templatize body
(rpush* (rcons* request (rpush* (if (assq 'sxml request)
'sxml (templatize request) request
'doctype xhtml-doctype) (rcons 'sxml (templatize request)
request))
'output-headers 'output-headers
(cons "Status" (status->string (rref request 'status 200))) (cons "Status" (status->string (rref request 'status 200)))
'output-headers 'output-headers
@ -98,6 +101,9 @@
((GET archives year? month? day?) page-archives) ((GET archives year? month? day?) page-archives)
((GET archives year! month! day! post!) page-show-post) ((GET archives year! month! day! post!) page-show-post)
((POST archives year! month! day! post!) page-new-comment) ((POST archives year! month! day! post!) page-new-comment)
((GET feed) page-feed-rss2)
((GET feed rss2) page-feed-rss2)
((GET feed atom) page-feed-atom)
((GET tags) page-show-tags) ((GET tags) page-show-tags)
((GET tags tag!) page-show-tag) ((GET tags tag!) page-show-tag)
((GET debug) page-debug) ((GET debug) page-debug)
@ -106,4 +112,4 @@
(define (handle-request request index) (define (handle-request request index)
(let ((handler (choose-handler request))) (let ((handler (choose-handler request)))
(pk (finalize (handler request index))))) (finalize (handler (rcons 'doctype xhtml-doctype request) index))))