continuing simplification work
This commit is contained in:
parent
eae227142c
commit
436ef22134
9 changed files with 129 additions and 179 deletions
|
@ -1,7 +1,3 @@
|
||||||
#! /bin/bash
|
|
||||||
# -*- scheme -*-
|
|
||||||
exec guile $GUILE_FLAGS -l $0 -e main -- "$@"
|
|
||||||
!#
|
|
||||||
;; Tekuti
|
;; Tekuti
|
||||||
;; Copyright (C) 2008 Andy Wingo <wingo at pobox dot com>
|
;; Copyright (C) 2008 Andy Wingo <wingo at pobox dot com>
|
||||||
|
|
||||||
|
@ -24,7 +20,7 @@ exec guile $GUILE_FLAGS -l $0 -e main -- "$@"
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This is the main script that will launch tekuti.
|
;; Module to parse options, etc before dropping into the main loop.
|
||||||
;;
|
;;
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
@ -77,7 +73,7 @@ exec guile $GUILE_FLAGS -l $0 -e main -- "$@"
|
||||||
(let ((run-utility (@ (ice-9 gds-client) run-utility)))
|
(let ((run-utility (@ (ice-9 gds-client) run-utility)))
|
||||||
(make-thread
|
(make-thread
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-backtrace run-utility)))))
|
(with-backtrace (run-utility))))))
|
||||||
opts))
|
opts))
|
||||||
|
|
||||||
(define (boot args)
|
(define (boot args)
|
||||||
|
|
|
@ -221,7 +221,7 @@
|
||||||
(assert-referenced-files-present
|
(assert-referenced-files-present
|
||||||
(append (map cdr lremove) (map caar lchange)) dents)
|
(append (map cdr lremove) (map caar lchange)) dents)
|
||||||
; (trc 'make-tree-deep treeish add remove change)
|
; (trc 'make-tree-deep treeish add remove change)
|
||||||
(make-tree-full
|
(git-mktree
|
||||||
(append
|
(append
|
||||||
(map cdr ladd)
|
(map cdr ladd)
|
||||||
(filter-map
|
(filter-map
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
#f)
|
#f)
|
||||||
((member (car dent) (map cadr lchange))
|
((member (car dent) (map cadr lchange))
|
||||||
(cdr lchange))
|
(cdr lchange))
|
||||||
((and (equal? (caddr dent) "tree")
|
((and (eq? (caddr dent) 'tree)
|
||||||
(member (car dent)
|
(member (car dent)
|
||||||
(map caar (append dadd dremove dchange))))
|
(map caar (append dadd dremove dchange))))
|
||||||
(let ((level-down (lambda (x)
|
(let ((level-down (lambda (x)
|
||||||
|
@ -243,11 +243,11 @@
|
||||||
(filter-map level-down dadd)
|
(filter-map level-down dadd)
|
||||||
(filter-map level-down dremove)
|
(filter-map level-down dremove)
|
||||||
(filter-map level-down dchange))
|
(filter-map level-down dchange))
|
||||||
"tree" "040000")))
|
'tree)))
|
||||||
(else dent)))
|
(else dent)))
|
||||||
(append (filter-map (lambda (x)
|
(append (filter-map (lambda (x)
|
||||||
(and (not (assoc (caar x) dents))
|
(and (not (assoc (caar x) dents))
|
||||||
(list (caar x) #f "tree" #f)))
|
(list (caar x) #f 'tree)))
|
||||||
dadd)
|
dadd)
|
||||||
dents))))))
|
dents))))))
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,9 @@
|
||||||
|
|
||||||
git git* ensure-git-repo git-ls-tree git-ls-subdirs
|
git git* ensure-git-repo git-ls-tree git-ls-subdirs
|
||||||
parse-metadata parse-commit commit-utc-timestamp
|
parse-metadata parse-commit commit-utc-timestamp
|
||||||
commit-parents make-tree git-rev-parse make-tree-full
|
commit-parents git-mktree git-rev-parse
|
||||||
create-blob git-update-ref
|
create-blob git-update-ref
|
||||||
|
git-commit-tree
|
||||||
|
|
||||||
write-indices read-indices))
|
write-indices read-indices))
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@
|
||||||
(match-lines (git "ls-tree" treeish (or path "."))
|
(match-lines (git "ls-tree" treeish (or path "."))
|
||||||
"^(.+) (.+) (.+)\t(.+)$" (_ mode type object name)
|
"^(.+) (.+) (.+)\t(.+)$" (_ mode type object name)
|
||||||
;; reversed for assoc
|
;; reversed for assoc
|
||||||
(list name object type mode)))
|
(list name object (string->symbol type))))
|
||||||
'()))
|
'()))
|
||||||
|
|
||||||
(define (git-ls-subdirs treeish path)
|
(define (git-ls-subdirs treeish path)
|
||||||
|
@ -184,13 +185,17 @@
|
||||||
(lambda (x) (eq? (car x) 'parent))
|
(lambda (x) (eq? (car x) 'parent))
|
||||||
(parse-commit commit))))
|
(parse-commit commit))))
|
||||||
|
|
||||||
(define (make-tree alist)
|
(define (git-mktree alist)
|
||||||
(string-trim-both
|
(string-trim-both
|
||||||
(git* '("mktree")
|
(git* '("mktree")
|
||||||
#:input (string-join
|
#:input (string-join
|
||||||
(map (lambda (pair)
|
(map (lambda (l)
|
||||||
(let ((name (car pair)) (sha (cdr pair)))
|
(format #f
|
||||||
(format #f "040000 tree ~a\t~a" sha name)))
|
(if (or (null? (cddr l))
|
||||||
|
(equal? (caddr l) 'blob))
|
||||||
|
"100644 blob ~a\t~a"
|
||||||
|
"040000 tree ~a\t~a")
|
||||||
|
(cadr l) (car l)))
|
||||||
alist)
|
alist)
|
||||||
"\n" 'suffix))))
|
"\n" 'suffix))))
|
||||||
|
|
||||||
|
@ -201,17 +206,6 @@
|
||||||
(string-trim-both
|
(string-trim-both
|
||||||
(git* '("hash-object" "-w" "--stdin") #:input contents)))
|
(git* '("hash-object" "-w" "--stdin") #:input contents)))
|
||||||
|
|
||||||
;; order: name object type mode
|
|
||||||
(define (make-tree-full alist)
|
|
||||||
(string-trim-both
|
|
||||||
(git* '("mktree")
|
|
||||||
#:input (string-join
|
|
||||||
(map (lambda (l)
|
|
||||||
(apply format #f "~a ~a ~a\t~a"
|
|
||||||
(reverse l)))
|
|
||||||
alist)
|
|
||||||
"\n" 'suffix))))
|
|
||||||
|
|
||||||
(define (git-update-ref refname proc count)
|
(define (git-update-ref refname proc count)
|
||||||
(let* ((ref (git-rev-parse refname))
|
(let* ((ref (git-rev-parse refname))
|
||||||
(commit (proc ref)))
|
(commit (proc ref)))
|
||||||
|
@ -225,46 +219,15 @@
|
||||||
(pk "failed to update the ref, trying again..." refname)
|
(pk "failed to update the ref, trying again..." refname)
|
||||||
(git-update-ref (git-rev-parse refname) (1- count))))))
|
(git-update-ref (git-rev-parse refname) (1- count))))))
|
||||||
|
|
||||||
|
(define (git-commit-tree tree parent message timestamp)
|
||||||
|
(string-trim-both
|
||||||
|
(git* (cons* "commit-tree" tree
|
||||||
|
(if parent (list "-p" parent) '()))
|
||||||
|
#:input message
|
||||||
|
#:env (if timestamp
|
||||||
|
(list "GIT_COMMMITTER=tekuti"
|
||||||
|
(format #f "GIT_COMMITTER_DATE=~a +0100" timestamp)
|
||||||
|
(format #f "GIT_AUTHOR_DATE=~a +0100" timestamp))))))
|
||||||
|
|
||||||
;; fixme: map-pairs
|
;; fixme: map-pairs
|
||||||
|
|
||||||
(define (assoc-list-ref alist key n default)
|
|
||||||
(let ((l (assoc key alist)))
|
|
||||||
(if l (list-ref l n) default)))
|
|
||||||
|
|
||||||
(define (write-indices indices oldref specs)
|
|
||||||
(let* ((master (assq-ref indices 'master))
|
|
||||||
(ts (commit-utc-timestamp master))
|
|
||||||
(env (list "GIT_COMMMITTER=tekuti"
|
|
||||||
(format #f "GIT_COMMITTER_DATE=~a +0100" ts)
|
|
||||||
(format #f "GIT_AUTHOR_DATE=~a +0100" ts)))
|
|
||||||
(tree (make-tree-full
|
|
||||||
(map (lambda (pair)
|
|
||||||
(list (symbol->string (car pair))
|
|
||||||
(create-blob
|
|
||||||
(with-output-to-string
|
|
||||||
(lambda ()
|
|
||||||
((assoc-list-ref specs (car pair) 2 write)
|
|
||||||
(cdr pair)))))
|
|
||||||
"blob" "100644"))
|
|
||||||
indices))))
|
|
||||||
(let ((new (string-trim-both
|
|
||||||
(git* (cons* "commit-tree" tree
|
|
||||||
(if oldref (list "-p" oldref) '()))
|
|
||||||
#:input "reindex\n" #:env env))))
|
|
||||||
(or (false-if-git-error
|
|
||||||
(git "update-ref" "refs/heads/index" new (or oldref "")))
|
|
||||||
(warn "could not update indexes ref"))
|
|
||||||
new)))
|
|
||||||
|
|
||||||
(define (read-indices specs)
|
|
||||||
(and=> (false-if-git-error (git-rev-parse "refs/heads/index"))
|
|
||||||
(lambda (ref)
|
|
||||||
(cons ref
|
|
||||||
(map (lambda (dent)
|
|
||||||
(cons (string->symbol (car dent))
|
|
||||||
(with-input-from-string
|
|
||||||
(git "show" (cadr dent))
|
|
||||||
(assoc-list-ref specs (string->symbol (car dent)) 3 read))))
|
|
||||||
(git-ls-tree (assq-ref (parse-commit ref) 'tree)
|
|
||||||
#f))))))
|
|
||||||
|
|
||||||
|
|
|
@ -26,20 +26,12 @@
|
||||||
|
|
||||||
(define-module (tekuti mod-lisp)
|
(define-module (tekuti mod-lisp)
|
||||||
#:use-module (ice-9 rdelim)
|
#:use-module (ice-9 rdelim)
|
||||||
#:use-module (ice-9 receive)
|
|
||||||
#:use-module (ice-9 stack-catch)
|
|
||||||
#:use-module ((srfi srfi-1) #:select (fold))
|
#:use-module ((srfi srfi-1) #:select (fold))
|
||||||
#:use-module (sxml simple)
|
|
||||||
#:use-module (sxml transform)
|
|
||||||
#:use-module (tekuti config)
|
#:use-module (tekuti config)
|
||||||
#:use-module (tekuti util)
|
#:use-module (tekuti util)
|
||||||
#:use-module (tekuti git) ; rev-parse
|
#:use-module (tekuti index) ; rev-parse
|
||||||
#:use-module (tekuti request)
|
#:use-module (tekuti request)
|
||||||
#:use-module (tekuti web)
|
#:use-module (tekuti web)
|
||||||
|
|
||||||
;; these for their reindex methods
|
|
||||||
#:use-module (tekuti post)
|
|
||||||
#:use-module (tekuti categories)
|
|
||||||
#:export (event-loop))
|
#:export (event-loop))
|
||||||
|
|
||||||
;;; thought: ignore SIGPIPE, otherwise apache dying will kill us
|
;;; thought: ignore SIGPIPE, otherwise apache dying will kill us
|
||||||
|
@ -69,23 +61,13 @@
|
||||||
(display "end\n" port))
|
(display "end\n" port))
|
||||||
|
|
||||||
(define (write-body request socket)
|
(define (write-body request socket)
|
||||||
(let ((sxml (rref request 'sxml #f)))
|
((rref request 'output error) socket))
|
||||||
(if sxml
|
|
||||||
(begin (display (rref request 'doctype "") socket)
|
|
||||||
(sxml->xml sxml socket))
|
|
||||||
(display "" socket))))
|
|
||||||
|
|
||||||
(define (request-output-headers request)
|
(define (request-output-headers request)
|
||||||
(let ((rheads '(("Content-Type" . output-type))))
|
(rref request 'output-headers '()))
|
||||||
(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 (read-headers socket))
|
||||||
(post-data (read-chars (string->number
|
(post-data (read-chars (string->number
|
||||||
(or (assoc-ref headers "content-length")
|
(or (assoc-ref headers "content-length")
|
||||||
"0"))
|
"0"))
|
||||||
|
@ -102,9 +84,11 @@
|
||||||
(write-headers '(("Status" . "500 Internal Server Error")
|
(write-headers '(("Status" . "500 Internal Server Error")
|
||||||
("Content-Type" . "text/plain"))
|
("Content-Type" . "text/plain"))
|
||||||
socket)
|
socket)
|
||||||
(write args socket)
|
(display "Sorry bub, had an error. Please let the admin know. Thanks!\n"
|
||||||
(newline)
|
socket)
|
||||||
(with-output-to-port socket backtrace))
|
(write headers) (newline)
|
||||||
|
(write args) (newline)
|
||||||
|
(backtrace))
|
||||||
(lambda args
|
(lambda args
|
||||||
(fluid-set! the-last-stack (make-stack #t 2 0))
|
(fluid-set! the-last-stack (make-stack #t 2 0))
|
||||||
(apply throw args)))
|
(apply throw args)))
|
||||||
|
@ -121,58 +105,6 @@
|
||||||
(proc socket)
|
(proc socket)
|
||||||
(shutdown socket 2))))
|
(shutdown socket 2))))
|
||||||
|
|
||||||
(define (with-time-debugging proc)
|
|
||||||
(let ((start (gettimeofday)))
|
|
||||||
(pk 'start-clock)
|
|
||||||
(let ((val (proc)))
|
|
||||||
(let ((stop (gettimeofday)))
|
|
||||||
(pk 'stop-clock (+ (- (car stop) (car start))
|
|
||||||
(* 1e-6 (- (cdr stop) (cdr start)))))
|
|
||||||
|
|
||||||
val))))
|
|
||||||
|
|
||||||
(define (write-hash h)
|
|
||||||
(write (hash-fold acons '() h)))
|
|
||||||
|
|
||||||
;; fixme: doesn't share structure with posts index
|
|
||||||
(define (read-hash)
|
|
||||||
(let ((h (make-hash-table)))
|
|
||||||
(for-each (lambda (pair)
|
|
||||||
(hash-set! h (car pair) (cdr pair)))
|
|
||||||
(read))
|
|
||||||
h))
|
|
||||||
|
|
||||||
(define indices
|
|
||||||
`((posts ,reindex-posts ,write ,read)
|
|
||||||
(categories ,reindex-categories ,write-hash ,read-hash)))
|
|
||||||
|
|
||||||
(use-modules (statprof))
|
|
||||||
(define (reindex oldindex master)
|
|
||||||
(with-backtrace
|
|
||||||
(lambda ()
|
|
||||||
(with-time-debugging
|
|
||||||
(lambda ()
|
|
||||||
(with-statprof #:hz 100
|
|
||||||
(fold (lambda (pair index)
|
|
||||||
(acons (car pair)
|
|
||||||
((cadr pair) oldindex index)
|
|
||||||
index))
|
|
||||||
(acons 'master master '())
|
|
||||||
indices)))))))
|
|
||||||
|
|
||||||
(define (maybe-reindex old-index)
|
|
||||||
(let ((master (git-rev-parse "master")))
|
|
||||||
(if (and old-index (equal? (assq-ref (cdr old-index) 'master) master))
|
|
||||||
old-index
|
|
||||||
(catch #t
|
|
||||||
(lambda ()
|
|
||||||
(let ((new-index (reindex (and=> old-index cdr) master)))
|
|
||||||
(cons (write-indices new-index (and=> old-index car) indices)
|
|
||||||
new-index)))
|
|
||||||
(lambda (key . args)
|
|
||||||
(warn "error while reindexing:" key args)
|
|
||||||
old-index)))))
|
|
||||||
|
|
||||||
(define (inner-loop socket index)
|
(define (inner-loop socket index)
|
||||||
(let* ((pair (accept socket))
|
(let* ((pair (accept socket))
|
||||||
(fd (car pair))
|
(fd (car pair))
|
||||||
|
@ -185,5 +117,5 @@
|
||||||
(with-socket
|
(with-socket
|
||||||
(lambda (socket)
|
(lambda (socket)
|
||||||
(format #t "entering inner loop\n")
|
(format #t "entering inner loop\n")
|
||||||
(inner-loop socket (read-indices indices)))))
|
(inner-loop socket (read-index)))))
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
(div (@ (class "post"))
|
(div (@ (class "post"))
|
||||||
(h3 (@ (class "meta"))
|
(h3 (@ (class "meta"))
|
||||||
,(post-readable-date post)
|
,(post-readable-date post)
|
||||||
" (" ,@(list-intersperse (post-category-links post)
|
" (" ,@(list-intersperse (post-tag-links post)
|
||||||
" | ")
|
" | ")
|
||||||
")")
|
")")
|
||||||
(div (@ (class "storycontent"))
|
(div (@ (class "storycontent"))
|
||||||
|
@ -191,14 +191,18 @@
|
||||||
(define page-delete-comment not-implemented)
|
(define page-delete-comment not-implemented)
|
||||||
(define page-delete-post not-implemented)
|
(define page-delete-post not-implemented)
|
||||||
|
|
||||||
|
;; fixme: borks in the no-tags case
|
||||||
(define (tag-cloud index)
|
(define (tag-cloud index)
|
||||||
(define (determine-sizes counts)
|
(define (determine-sizes counts)
|
||||||
(let ((maxcount (apply max counts)))
|
(let ((maxcount (apply max counts)))
|
||||||
(map (lambda (x)
|
(map (lambda (x)
|
||||||
(floor (+ 80 (* 120 (/ x maxcount)))))
|
(floor (+ 80 (* 120 (/ x maxcount)))))
|
||||||
counts)))
|
counts)))
|
||||||
(let* ((cats (hash-fold (lambda (k v seed) (acons k (length v) seed))
|
(let* ((hash (assq-ref index 'tags))
|
||||||
'() (assq-ref index 'categories)))
|
(cats (if hash
|
||||||
|
(hash-fold (lambda (k v seed) (acons k (length v) seed))
|
||||||
|
'() hash)
|
||||||
|
'()))
|
||||||
(top-20 (dsu-sort (take-max (dsu-sort cats cdr >) 20)
|
(top-20 (dsu-sort (take-max (dsu-sort cats cdr >) 20)
|
||||||
car string<?)))
|
car string<?)))
|
||||||
`(ul (li (@ (style "line-height: 150%"))
|
`(ul (li (@ (style "line-height: 150%"))
|
||||||
|
@ -218,9 +222,10 @@
|
||||||
(define (main-sidebar request index)
|
(define (main-sidebar request index)
|
||||||
(sidebar-ul
|
(sidebar-ul
|
||||||
`((li (h2 (a (@ (href ,(relurl "feed/atom")))
|
`((li (h2 (a (@ (href ,(relurl "feed/atom")))
|
||||||
(img (@ (href ,(relurl "wp-content/feed-icon-14x14.png"))
|
"subscribe "
|
||||||
|
(img (@ (src ,(relurl "wp-content/feed-icon-14x14.png"))
|
||||||
(alt "subscribe to this feed")))
|
(alt "subscribe to this feed")))
|
||||||
" subscribe")))
|
)))
|
||||||
(li (h2 "tags "
|
(li (h2 "tags "
|
||||||
(a (@ (href ,(string-append *public-url-base* "tags/")))
|
(a (@ (href ,(string-append *public-url-base* "tags/")))
|
||||||
">>"))
|
">>"))
|
||||||
|
@ -372,6 +377,10 @@
|
||||||
(date->string (time-utc->date (make-time time-utc 0 timestamp) 0)
|
(date->string (time-utc->date (make-time time-utc 0 timestamp) 0)
|
||||||
"~Y-~m-~dT~H:~M:~SZ"))
|
"~Y-~m-~dT~H:~M:~SZ"))
|
||||||
|
|
||||||
|
(define (timestamp->rfc822-date timestamp)
|
||||||
|
(date->string (time-utc->date (make-time time-utc 0 timestamp) 0)
|
||||||
|
"~a, ~d ~b ~Y ~H:~M:~S GMT"))
|
||||||
|
|
||||||
(define (request-relurl request)
|
(define (request-relurl request)
|
||||||
(let ((headers (rref request 'headers)))
|
(let ((headers (rref request 'headers)))
|
||||||
(let ((server (or (assoc-ref headers "Host")
|
(let ((server (or (assoc-ref headers "Host")
|
||||||
|
@ -392,7 +401,10 @@
|
||||||
'status 304
|
'status 304
|
||||||
'doctype #f))
|
'doctype #f))
|
||||||
(else
|
(else
|
||||||
(rcons* request
|
(rcons* (rpush 'output-headers (cons "Last-Modified"
|
||||||
|
(timestamp->rfc822-date
|
||||||
|
last-modified))
|
||||||
|
request)
|
||||||
'doctype ""
|
'doctype ""
|
||||||
'content-type "application/atom+xml"
|
'content-type "application/atom+xml"
|
||||||
'sxml `(feed
|
'sxml `(feed
|
||||||
|
|
|
@ -35,10 +35,10 @@
|
||||||
#:use-module (tekuti filters)
|
#:use-module (tekuti filters)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-19)
|
#:use-module (srfi srfi-19)
|
||||||
#:export (reindex-posts post-from-tree post-from-key post-categories
|
#:export (reindex-posts post-from-tree post-from-key post-tags
|
||||||
post-timestamp
|
post-timestamp post-key
|
||||||
post-sxml-content post-raw-content all-published-posts
|
post-sxml-content post-raw-content all-published-posts
|
||||||
post-readable-date post-category-links post-sxml-n-comments
|
post-readable-date post-tag-links post-sxml-n-comments
|
||||||
post-sxml-comments))
|
post-sxml-comments))
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,14 +49,17 @@
|
||||||
(equal? (assq-ref post-alist 'status) "publish"))
|
(equal? (assq-ref post-alist 'status) "publish"))
|
||||||
|
|
||||||
(define (post-timestamp post-alist)
|
(define (post-timestamp post-alist)
|
||||||
(or (assq-ref post-alist 'timestamp) #f))
|
(assq-ref post-alist 'timestamp))
|
||||||
|
|
||||||
(define (post-categories post-alist)
|
(define (post-tags post-alist)
|
||||||
(or (assq-ref post-alist 'categories) '()))
|
(or (assq-ref post-alist 'tags) '()))
|
||||||
|
|
||||||
|
(define (post-key post)
|
||||||
|
(assq-ref post 'key))
|
||||||
|
|
||||||
(define *post-spec*
|
(define *post-spec*
|
||||||
`((timestamp . ,string->number)
|
`((timestamp . ,string->number)
|
||||||
(categories . ,(lambda (v) (map string-trim-both (string-split v #\,))))
|
(tags . ,(lambda (v) (map string-trim-both (string-split v #\,))))
|
||||||
(title . ,identity)))
|
(title . ,identity)))
|
||||||
|
|
||||||
(define (post-from-tree encoded-name sha1)
|
(define (post-from-tree encoded-name sha1)
|
||||||
|
@ -80,12 +83,14 @@
|
||||||
(make-time time-utc 0 (assq-ref post 'timestamp)))))
|
(make-time time-utc 0 (assq-ref post 'timestamp)))))
|
||||||
(date->string date "~e ~B ~Y ~l:~M ~p")))
|
(date->string date "~e ~B ~Y ~l:~M ~p")))
|
||||||
|
|
||||||
(define (post-category-links post)
|
;; hack :-/
|
||||||
(map (lambda (cat)
|
(define (tag-link tagname)
|
||||||
`(a (@ (href ,(string-append *public-url-base* "tags/"
|
`(a (@ (href ,(string-append *public-url-base* "tags/"
|
||||||
(url:encode cat))))
|
(url:encode tagname))))
|
||||||
,cat))
|
,tagname))
|
||||||
(post-categories post)))
|
|
||||||
|
(define (post-tag-links post)
|
||||||
|
(map tag-link (post-tags post)))
|
||||||
|
|
||||||
(define (post-from-key master key)
|
(define (post-from-key master key)
|
||||||
(let ((pairs (git-ls-subdirs master key)))
|
(let ((pairs (git-ls-subdirs master key)))
|
||||||
|
|
|
@ -20,26 +20,33 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This is the main script that will launch tekuti.
|
;; Tags, tags, tags
|
||||||
;;
|
;;
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (tekuti categories)
|
(define-module (tekuti tags)
|
||||||
#:use-module (tekuti util)
|
#:use-module (tekuti util)
|
||||||
|
#:use-module (tekuti url)
|
||||||
|
#:use-module (tekuti config)
|
||||||
#:use-module (tekuti post)
|
#:use-module (tekuti post)
|
||||||
#:use-module (tekuti git)
|
#:use-module (tekuti git)
|
||||||
#:export (reindex-categories))
|
#:export (tag-link reindex-tags))
|
||||||
|
|
||||||
(define (compute-categories posts)
|
(define (tag-link tagname)
|
||||||
|
`(a (@ (href ,(string-append *public-url-base* "tags/"
|
||||||
|
(url:encode tagname))))
|
||||||
|
,tagname))
|
||||||
|
|
||||||
|
(define (compute-tags posts)
|
||||||
(let ((hash (make-hash-table)))
|
(let ((hash (make-hash-table)))
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (post)
|
(lambda (post)
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (cat)
|
(lambda (cat)
|
||||||
(hash-push! hash cat (assq-ref post 'key)))
|
(hash-push! hash cat (assq-ref post 'key)))
|
||||||
(post-categories post)))
|
(post-tags post)))
|
||||||
posts)
|
posts)
|
||||||
hash))
|
hash))
|
||||||
|
|
||||||
(define (reindex-categories old-index index)
|
(define (reindex-tags old-index index)
|
||||||
(compute-categories (assq-ref index 'posts)))
|
(compute-tags (assq-ref index 'posts)))
|
|
@ -29,8 +29,8 @@
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:export (expanduser match-lines dbg unwind-protect dbg dsu-sort
|
#:export (expanduser match-lines dbg unwind-protect dbg dsu-sort
|
||||||
hash-push! list-has-length? list-head-match mapn
|
hash-push! list-has-length? list-head-match mapn
|
||||||
take-max
|
take-max read-hash write-hash
|
||||||
list-intersperse with-backtrace define-memoized))
|
list-intersperse with-backtrace with-time-debugging define-memoized))
|
||||||
|
|
||||||
(define (expanduser path)
|
(define (expanduser path)
|
||||||
(let ((parts (string-split path #\/)))
|
(let ((parts (string-split path #\/)))
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
(force-output cep)
|
(force-output cep)
|
||||||
(apply throw key args)))
|
(apply throw key args)))
|
||||||
|
|
||||||
(define (with-backtrace proc)
|
(define (with-backtrace* proc)
|
||||||
(debug-enable 'backtrace)
|
(debug-enable 'backtrace)
|
||||||
(start-stack 'with-backtrace
|
(start-stack 'with-backtrace
|
||||||
(catch #t
|
(catch #t
|
||||||
|
@ -125,6 +125,24 @@
|
||||||
(fluid-set! the-last-stack (make-stack #t 2 0))
|
(fluid-set! the-last-stack (make-stack #t 2 0))
|
||||||
(apply throw args)))))
|
(apply throw args)))))
|
||||||
|
|
||||||
|
(define-macro (with-backtrace . forms)
|
||||||
|
`(,with-backtrace* (lambda () ,@forms)))
|
||||||
|
|
||||||
|
(define (gettimeofday-diff prev)
|
||||||
|
(let ((now (gettimeofday)))
|
||||||
|
(+ (- (car now) (car prev))
|
||||||
|
(* 1e-6 (- (cdr now) (cdr prev))))))
|
||||||
|
|
||||||
|
(define (with-time-debugging* proc)
|
||||||
|
(pk 'start-clock)
|
||||||
|
(let ((start (gettimeofday)))
|
||||||
|
(unwind-protect
|
||||||
|
(proc)
|
||||||
|
(pk 'stop-clock (gettimeofday-diff start)))))
|
||||||
|
|
||||||
|
(define-macro (with-time-debugging . forms)
|
||||||
|
`(,with-time-debugging* (lambda () ,@forms)))
|
||||||
|
|
||||||
(define (memoize1 proc)
|
(define (memoize1 proc)
|
||||||
(let ((old-args #f) (cache #f) (proc proc))
|
(let ((old-args #f) (cache #f) (proc proc))
|
||||||
(lambda args
|
(lambda args
|
||||||
|
@ -139,3 +157,14 @@
|
||||||
`(begin
|
`(begin
|
||||||
(define ,form ,@body)
|
(define ,form ,@body)
|
||||||
(set! ,(car form) (,memoize1 ,(car form)))))
|
(set! ,(car form) (,memoize1 ,(car form)))))
|
||||||
|
|
||||||
|
(define (write-hash h)
|
||||||
|
(write (hash-fold acons '() h)))
|
||||||
|
|
||||||
|
(define (read-hash)
|
||||||
|
(let ((h (make-hash-table)))
|
||||||
|
(for-each (lambda (pair)
|
||||||
|
(hash-set! h (car pair) (cdr pair)))
|
||||||
|
(read))
|
||||||
|
h))
|
||||||
|
|
||||||
|
|
|
@ -63,13 +63,19 @@
|
||||||
bindings))
|
bindings))
|
||||||
,@body))))
|
,@body))))
|
||||||
|
|
||||||
|
(define (make-output request)
|
||||||
|
(lambda (port)
|
||||||
|
(let ((sxml (or (rref request 'sxml #f)
|
||||||
|
(templatize request))))
|
||||||
|
(if sxml
|
||||||
|
(begin (display (rref request 'doctype "") port)
|
||||||
|
(sxml->xml sxml port))
|
||||||
|
(display "" port)))))
|
||||||
|
|
||||||
(define (finalize request)
|
(define (finalize request)
|
||||||
;; update output headers
|
;; update output headers
|
||||||
;; templatize body
|
;; templatize body
|
||||||
(rpush* (if (assq 'sxml request)
|
(rpush* (rcons 'output (make-output request) request)
|
||||||
request
|
|
||||||
(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
|
||||||
|
|
Loading…
Reference in a new issue