some cleanup of how the lisp server works
This commit is contained in:
		
							parent
							
								
									d653ccdf9f
								
							
						
					
					
						commit
						36fe8f6a63
					
				
					 3 changed files with 20 additions and 145 deletions
				
			
		
							
								
								
									
										2
									
								
								TODO.org
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO.org
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
:CATEGORY: dev
 | 
			
		||||
:END:
 | 
			
		||||
 | 
			
		||||
* TODO Move to the lisp server and htmx
 | 
			
		||||
* DONE Move to the lisp server and htmx
 | 
			
		||||
SCHEDULED: <2024-04-24 Wed>
 | 
			
		||||
I want to move all validation and form processing to the lisp server and htmx. This way I'm not doing javascript which is sometimes complicated since I use it so infrequently, however, this will likely be a bit more involved, so I'll need to learn htmx, but I think it'll be better in the end, since htmx more akin to what the web was supposed to be like.
 | 
			
		||||
* TODO Add registration cost and info to home page, thank you page, and thank you responses
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1796,6 +1796,10 @@ select {
 | 
			
		|||
  margin-top: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mt-2 {
 | 
			
		||||
  margin-top: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mb-8 {
 | 
			
		||||
  margin-bottom: 2rem;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1900,10 +1904,6 @@ select {
 | 
			
		|||
  margin-left: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mt-2 {
 | 
			
		||||
  margin-top: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.-mr-\[100\%\] {
 | 
			
		||||
  margin-right: -100%;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1980,6 +1980,10 @@ select {
 | 
			
		|||
  height: 24rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.h-0 {
 | 
			
		||||
  height: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.h-12 {
 | 
			
		||||
  height: 3rem;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2048,10 +2052,6 @@ select {
 | 
			
		|||
  height: 1000px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.h-0 {
 | 
			
		||||
  height: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.max-h-\[5rem\] {
 | 
			
		||||
  max-height: 5rem;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2459,16 +2459,16 @@ select {
 | 
			
		|||
  background-color: rgba(var(--color-neutral-500), var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bg-\[\#ef4444\] {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(239 68 68 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bg-primary-700 {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgba(var(--color-primary-700), var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bg-\[\#ef4444\] {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgb(239 68 68 / var(--tw-bg-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bg-primary-600 {
 | 
			
		||||
  --tw-bg-opacity: 1;
 | 
			
		||||
  background-color: rgba(var(--color-primary-600), var(--tw-bg-opacity));
 | 
			
		||||
| 
						 | 
				
			
			@ -2630,10 +2630,6 @@ select {
 | 
			
		|||
  padding: 1.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.p-8 {
 | 
			
		||||
  padding: 2rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.px-0 {
 | 
			
		||||
  padding-left: 0px;
 | 
			
		||||
  padding-right: 0px;
 | 
			
		||||
| 
						 | 
				
			
			@ -4734,12 +4730,12 @@ pre {
 | 
			
		|||
  color: rgba(var(--color-neutral-500), var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.invalid\:text-\[\#F39\]:invalid {
 | 
			
		||||
.invalid\:text-\[\#f39\]:invalid {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(255 51 153 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.invalid\:text-\[\#f39\]:invalid {
 | 
			
		||||
.invalid\:text-\[\#F39\]:invalid {
 | 
			
		||||
  --tw-text-opacity: 1;
 | 
			
		||||
  color: rgb(255 51 153 / var(--tw-text-opacity));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4972,58 +4968,22 @@ pre {
 | 
			
		|||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mt-10 {
 | 
			
		||||
  margin-top: 2.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mb-10 {
 | 
			
		||||
  margin-bottom: 2.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mb-16 {
 | 
			
		||||
  margin-bottom: 4rem;
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mb-32 {
 | 
			
		||||
  margin-bottom: 8rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mb-24 {
 | 
			
		||||
  margin-bottom: 6rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:mb-32 {
 | 
			
		||||
  margin-bottom: 8rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:h-8 {
 | 
			
		||||
  height: 2rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:h-24 {
 | 
			
		||||
  height: 6rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:h-32 {
 | 
			
		||||
  height: 8rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:h-2 {
 | 
			
		||||
  height: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:basis-full {
 | 
			
		||||
  flex-basis: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:p-8 {
 | 
			
		||||
  padding: 2rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid ~ .peer-invalid\:p-2 {
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:empty ~ .peer-empty\:visible {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:empty ~ .peer-empty\:invisible {
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5036,22 +4996,6 @@ pre {
 | 
			
		|||
  height: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:focus ~ .peer-focus\:visible {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid:focus ~ .peer-invalid\:peer-focus\:visible {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:focus:invalid ~ .peer-focus\:peer-invalid\:visible {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.peer:invalid:focus ~ .peer-invalid\:peer-focus\:p-2 {
 | 
			
		||||
  padding: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[dir="ltr"] .ltr\:right-0 {
 | 
			
		||||
  right: 0px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -240,30 +240,6 @@
 | 
			
		|||
              :verbose t)
 | 
			
		||||
    ))
 | 
			
		||||
 | 
			
		||||
(defun print-hash-entry (key value)
 | 
			
		||||
  (format t "~S: ~S~%" key
 | 
			
		||||
          (if (hash-table-p value)
 | 
			
		||||
              (maphash 'print-hash-entry value)
 | 
			
		||||
              (if (simple-vector-p value)
 | 
			
		||||
                  (loop
 | 
			
		||||
                    :for item
 | 
			
		||||
                      :in (setq value (coerce value 'list))
 | 
			
		||||
                    :do (maphash 'print-hash-entry item)) 
 | 
			
		||||
                  value))))
 | 
			
		||||
 | 
			
		||||
(defun process-form (form)
 | 
			
		||||
  "Processes the form and sends it on"
 | 
			
		||||
  (uiop:println "---")
 | 
			
		||||
  (maphash 'print-hash-entry form)
 | 
			
		||||
  (uiop:println "---"))
 | 
			
		||||
 | 
			
		||||
(defun save-string-file (string file-path)
 | 
			
		||||
  "save a file that is represented as a string to disk that came from a multipart/form-data"
 | 
			
		||||
  (serapeum/bundle:write-string-into-file string file-path
 | 
			
		||||
                                          :if-exists :overwrite
 | 
			
		||||
                                          :if-does-not-exist :create
 | 
			
		||||
                                          :external-format :latin-1))
 | 
			
		||||
 | 
			
		||||
(defun mail-mt-form (form attachment)
 | 
			
		||||
  "Takes the form as an alist and sends a table formatted email
 | 
			
		||||
with the image attached to us"
 | 
			
		||||
| 
						 | 
				
			
			@ -381,7 +357,7 @@ with the image attached"
 | 
			
		|||
                         (:th (car row))
 | 
			
		||||
                         (:td (cdr row))))))))))))
 | 
			
		||||
 | 
			
		||||
(tbnl:define-easy-handler (respond :uri "/health-form") ()
 | 
			
		||||
(tbnl:define-easy-handler (health-form :uri "/health-form") ()
 | 
			
		||||
  (setf (tbnl:header-out :access-control-expose-headers) "*")
 | 
			
		||||
  (let* ((data (tbnl:post-parameters* tbnl:*request*))
 | 
			
		||||
         (registration (cdr (assoc "registration" data :test 'string=)))
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +409,7 @@ with the image attached"
 | 
			
		|||
              (:p :class "text-md"
 | 
			
		||||
                  "If you'd like to pay for your registration go to the donate tab in the top right when you are ready and find the camp registration option.")))))))
 | 
			
		||||
 | 
			
		||||
(hunchentoot:define-easy-handler (respond :uri "/camp-api") ()
 | 
			
		||||
(hunchentoot:define-easy-handler (camp-form :uri "/camp-api") ()
 | 
			
		||||
  (let* ((request-type (hunchentoot:request-method hunchentoot:*request*))
 | 
			
		||||
         (data (hunchentoot:post-parameters* hunchentoot:*request*))
 | 
			
		||||
         (registration (cdr (assoc "registration" data :test 'string=)))
 | 
			
		||||
| 
						 | 
				
			
			@ -472,51 +448,6 @@ with the image attached"
 | 
			
		|||
          (uiop:println (tbnl:headers-out*))
 | 
			
		||||
          (mail-camp-form data nil)))))
 | 
			
		||||
 | 
			
		||||
(defun define-post-form-handler (uri mail-function)
 | 
			
		||||
  "Take a uri and a mailer function and define a handler in hunchentoot
 | 
			
		||||
for forms to POST to."
 | 
			
		||||
  (hunchentoot:define-easy-handler (respond :uri uri) ()
 | 
			
		||||
    (setf (hunchentoot:content-type*) "plain/text")
 | 
			
		||||
    (let* ((request-type (hunchentoot:request-method hunchentoot:*request*))
 | 
			
		||||
           (post-data (hunchentoot:post-parameters* hunchentoot:*request*))
 | 
			
		||||
           (attachment nil)
 | 
			
		||||
           (first-name nil)
 | 
			
		||||
           (last-name nil))
 | 
			
		||||
      (cond ((eq request-type :get) nil)
 | 
			
		||||
            ((eq request-type :post)
 | 
			
		||||
             (loop :for d :in post-data
 | 
			
		||||
                   :do (progn
 | 
			
		||||
                         (uiop:println d)
 | 
			
		||||
                         (if (string= "firstname" (car d))
 | 
			
		||||
                             (progn
 | 
			
		||||
                               (uiop:println (cdr d))
 | 
			
		||||
                               (setf first-name (cdr d))))
 | 
			
		||||
                         (if (string= "lastname" (car d))
 | 
			
		||||
                             (progn
 | 
			
		||||
                               (uiop:println (cdr d))
 | 
			
		||||
                               (setf last-name (cdr d))))
 | 
			
		||||
                         (if (string= "image" (car d))
 | 
			
		||||
                             (let ((path (path-join
 | 
			
		||||
                                          hunchentoot:*tmp-directory*
 | 
			
		||||
                                          (format nil "~a_~a.~a" first-name last-name
 | 
			
		||||
                                                  (cadr (uiop:split-string
 | 
			
		||||
                                                         (car (last d 2)) :separator "."))))))
 | 
			
		||||
                               (uiop:copy-file
 | 
			
		||||
                                (cadr d)
 | 
			
		||||
                                (path-join
 | 
			
		||||
                                 hunchentoot:*tmp-directory*
 | 
			
		||||
                                 (format nil "~a_~a.~a" first-name last-name
 | 
			
		||||
                                         (cadr (uiop:split-string
 | 
			
		||||
                                                (car (last d 2)) :separator ".")))))
 | 
			
		||||
                               (setf attachment path)
 | 
			
		||||
                               (uiop:println attachment)))))
 | 
			
		||||
             (if (funcall mail-function post-data attachment)
 | 
			
		||||
                 (format nil "thankyou")))))))
 | 
			
		||||
 | 
			
		||||
(define-post-form-handler "/mt-form" 'mail-mt-form)
 | 
			
		||||
(define-post-form-handler "/health-form" 'mail-health-form)
 | 
			
		||||
(define-post-form-handler "/camp-form" 'mail-camp-form)
 | 
			
		||||
 | 
			
		||||
(defun main ()
 | 
			
		||||
  (start-server 4242)
 | 
			
		||||
  (format t "Server has started on port 4242~&")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue