|
@@ -1,12 +1,18 @@
|
1
|
1
|
(eval-when (:compile-toplevel)
|
2
|
|
- (ql:quickload '(zs3)))
|
|
2
|
+ (ql:quickload 'zs3))
|
3
|
3
|
|
4
|
4
|
(defpackage :coleslaw-s3
|
5
|
|
- (:use :cl :coleslaw :zs3))
|
|
5
|
+ (:use :cl :zs3)
|
|
6
|
+ (:import-from :coleslaw #:deploy)
|
|
7
|
+ (:import-from :zs3 #:all-keys
|
|
8
|
+ #:etag
|
|
9
|
+ #:file-etag
|
|
10
|
+ #:put-file)
|
|
11
|
+ (:export #:enable))
|
6
|
12
|
|
7
|
13
|
(in-package :coleslaw-s3)
|
8
|
14
|
|
9
|
|
-(defparameter *credentials* (get-credentials :s3)
|
|
15
|
+(defparameter *credentials* nil
|
10
|
16
|
"The credentials to authenticate with Amazon Web Services.
|
11
|
17
|
Stored in a file with the access key on the first line
|
12
|
18
|
and the secret key on the second.")
|
|
@@ -26,34 +32,29 @@ and the secret key on the second.")
|
26
|
32
|
(defun content-type (extension)
|
27
|
33
|
(cdr (assoc extension *content-type-map* :test #'equal)))
|
28
|
34
|
|
29
|
|
-(defun init ()
|
30
|
|
- (unless *credentials*
|
31
|
|
- (set-credentials :s3 (file-credentials "~/.aws"))
|
32
|
|
- (setf *credentials* (get-credentials :s3))))
|
33
|
|
-
|
34
|
|
-(defun stale-keys (&key cache)
|
35
|
|
- (loop for key being the hash-values in cache collecting key))
|
36
|
|
-
|
37
|
|
-(defun s3-sync (filepath &key bucket dir public-p cache)
|
38
|
|
- (flet ((compute-key (namestring)
|
39
|
|
- (subseq namestring (length (namestring (truename dir))))))
|
40
|
|
- (let* ((etag (file-etag filepath))
|
41
|
|
- (namestring (namestring filepath))
|
42
|
|
- (key (compute-key namestring)))
|
43
|
|
- (if (gethash etag cache)
|
44
|
|
- (remhash etag cache)
|
45
|
|
- (put-file filepath bucket key :public public-p
|
46
|
|
- :content-type (content-type (pathname-type filepath)))))))
|
47
|
|
-
|
48
|
|
-(defun dir->s3 (dir &key bucket cache public-p)
|
49
|
|
- (cl-fad:walk-directory dir (lambda (file)
|
50
|
|
- (s3-sync file :cache cache :dir dir
|
51
|
|
- :bucket bucket :public-p public-p))))
|
52
|
|
-
|
53
|
|
-(defmethod coleslaw::render-site :after ()
|
54
|
|
- (init)
|
55
|
|
- (let* ((keys (all-keys *bucket*)))
|
56
|
|
- (loop for key across keys do (setf (gethash (etag key) *cache*) key))
|
57
|
|
- (dir->s3 coleslaw::*output-dir* :bucket *bucket* :cache *cache* :public-p t)
|
58
|
|
- (when (stale-keys :cache *cache*)
|
59
|
|
- (delete-objects (stale-keys) *bucket*))))
|
|
35
|
+(defun stale-keys ()
|
|
36
|
+ (loop for key being the hash-values in *cache* collecting key))
|
|
37
|
+
|
|
38
|
+(defun s3-sync (filepath dir)
|
|
39
|
+ (let ((etag (file-etag filepath))
|
|
40
|
+ (key (enough-namestring filepath dir)))
|
|
41
|
+ (if (gethash etag *cache*)
|
|
42
|
+ (remhash etag *cache*)
|
|
43
|
+ (put-file filepath *bucket* key :public t
|
|
44
|
+ :content-type (content-type (pathname-type filepath))))))
|
|
45
|
+
|
|
46
|
+(defun dir->s3 (dir)
|
|
47
|
+ (flet ((upload (file)
|
|
48
|
+ (s3-sync file dir :public-p t)))
|
|
49
|
+ (cl-fad:walk-directory dir #'upload)))
|
|
50
|
+
|
|
51
|
+(defmethod deploy :after (staging)
|
|
52
|
+ (let ((blog (deploy coleslaw::*config*)))
|
|
53
|
+ (loop for key across (all-keys *bucket*)
|
|
54
|
+ do (setf (gethash (etag key) *cache*) key))
|
|
55
|
+ (dir->s3 blog)
|
|
56
|
+ (delete-objects (stale-keys) *bucket*)))
|
|
57
|
+
|
|
58
|
+(defun enable (&key auth-file bucket)
|
|
59
|
+ (setf *credentials* (file-credentials auth-file)
|
|
60
|
+ *bucket* bucket))
|