(in-package #:photo-store) (eval-when (:compile-toplevel :load-toplevel :execute) (restas::register-pkgmodule-traits 'photo-store) (restas:reconnect-all-routes)) ;; photos: id | album_id | filename | size | taken | width | height | lat | lon ;; albums: id | parent_id | path | date | name | description | cover_id | accessibility (defstruct photo url title width height) (defun load-photo (path) (let ((info (load-photo-info path))) (make-photo :url (map-path path) :title (aget :name info) :width (first (aget :dim info)) :height (second (aget :dim info))))) (defun load-photos-from-dir (directory) (mapcar 'load-photo (remove-if-not #'(lambda (p) (equal (string-downcase (pathname-type p)) "jpg")) (uiop:directory-files directory)))) (defvar *path-url-mapping* nil "alist of path-2-url mapping") (defun map-path (path) (loop for (base-path . base-url) in *path-url-mapping* for rel-path = (uiop:subpathp path base-path) when rel-path do (return (concatenate 'string base-url (namestring rel-path))) finally (error "Can't map path ~S" path))) (defmethod yason:encode ((photo photo) &optional (stream *standard-output*)) (yason:with-output (stream) (yason:with-object () (yason:encode-object-element "src" (photo-url photo)) (yason:encode-object-element "w" (photo-width photo)) (yason:encode-object-element "h" (photo-height photo)) (yason:encode-object-element "title" (photo-title photo))))) (restas:define-route main ("") (asdf:system-relative-pathname :photo-store "index.html")) ;; Assets file path (defparameter *assets-path* (asdf:system-relative-pathname :photo-store "assets/")) (restas:define-route assets/css ("css/:file" :content-type "text/css") (merge-pathnames file *assets-path*)) (restas:define-route assets/js ("js/:file" :content-type "application/x-javascript") (merge-pathnames file *assets-path*)) (defvar *incoming-path* nil "Path for incoming photos") (restas:define-route incoming ("incoming/" :content-type "application/json") (with-output-to-string (stream) (yason:encode (loop for subdir in (uiop:subdirectories *incoming-path*) append (load-photos-from-dir subdir)) stream))) (defun start (&key (address "0.0.0.0") (port 8800)) (restas:start '#:photo-store :address address :port port))