diff --git a/bin/6625c400-0ccf-11f0-8230-eb390952483c b/bin/6625c400-0ccf-11f0-8230-eb390952483c new file mode 100644 index 0000000..2699a20 --- /dev/null +++ b/bin/6625c400-0ccf-11f0-8230-eb390952483c @@ -0,0 +1 @@ +hello world!!!! \ No newline at end of file diff --git a/main.fasl b/main.fasl new file mode 100644 index 0000000..a56ea7d Binary files /dev/null and b/main.fasl differ diff --git a/main.lisp b/main.lisp new file mode 100644 index 0000000..3180043 --- /dev/null +++ b/main.lisp @@ -0,0 +1,88 @@ + +(ql:quickload "hunchentoot") +(ql:quickload "easy-routes") +(ql:quickload "djula") +(ql:quickload "frugal-uuid") + +(setf *default-pathname-defaults* (uiop:getcwd)) + +;;;; if you're gonna run a public instance, change to the url other people +;;;; will use to connect! +(defvar *server-external-address* "http://localhost:8080/") +(defvar *server* nil) + +;; we probably don't actually need a template for the root, +;; it's more or less static anyhow. +;; i guess retrieving a paste is the only place that actually needs +;; the dynamic templating thingy + +(defparameter *root-template* + (uiop:read-file-string "root.html")) + +(defparameter *paste-template* + (uiop:read-file-string "paste.html")) + +;; google code +;; holy hell, actual business logic + +(defun get-paste-contents (id) + "read file lmao. also do some checks. we don't want LFI" + (let ((path (probe-file (concatenate 'string "bin/" id)))) + (if (and path + (not (search "." id)) + (not (search "/" id))) + (uiop:read-file-string path) + nil))) + + + +(defun render-root () + (djula:render-template* + (djula:compile-string *root-template*) + nil)) +(defun render-paste (id) + (djula:render-template* + (djula:compile-string *paste-template*) + nil + :contents (or (get-paste-contents id) "err: paste not found") + :link-home *server-external-address* + :link-bin (concatenate 'string *server-external-address* "bin/" id) + :link-raw (concatenate 'string *server-external-address* "raw/" id))) + +(defun new-paste-file () + (let ((id (fuuid:to-string (fuuid:make-v1)))) + (if (get-paste-contents id) + (new-paste-file) + id))) + +(defun create-new-paste (contents) + "Returns the url to the new paste" + (let ((path (new-paste-file))) + (with-open-file (s (concatenate 'string "bin/" path) :direction :output) + (princ contents s)) + path)) + + +(easy-routes:defroute root ("/" :method :get) () + (render-root)) + +(easy-routes:defroute paste ("/bin/:n") () + (render-paste n)) + +(easy-routes:defroute raw ("/raw/:n") () + (get-paste-contents n)) + +;; todo: handle new pastes TODO: doesn't work, fix. +(easy-routes:defroute new ("/new" :method :post) (content) + (let ((path (create-new-paste content))) + (format t "created new bin ~a~%" path) + (hunchentoot:redirect (concatenate 'string "/bin/" path)))) + + +(defun start-server (&key (port 8080)) + (format t "Starting server on port ~a~%" port) + (force-output) + (setf *server* (make-instance 'easy-routes:easy-routes-acceptor :port port)) + (hunchentoot:start *server*)) +(defun stop-server () + (hunchentoot:stop *server*)) diff --git a/main.lisp~ b/main.lisp~ new file mode 100644 index 0000000..e8bfe1b --- /dev/null +++ b/main.lisp~ @@ -0,0 +1,71 @@ + +(ql:quickload "hunchentoot") +(ql:quickload "easy-routes") +(ql:quickload "djula") + +(setf *default-pathname-defaults* (uiop:getcwd)) + +;;;; if you're gonna run a public instance, change to the url other people +;;;; will use to connect! +(defvar *server-external-address* "http://localhost:8080/") +(defvar *server* nil) + +;; we probably don't actually need a template for the root, +;; it's more or less static anyhow. +;; i guess retrieving a paste is the only place that actually needs +;; the dynamic templating thingy + +(defparameter *root-template* + (uiop:read-file-string "root.html")) + +(defparameter *paste-template* + (uiop:read-file-string "paste.html")) + +;; google code +;; holy hell, actual business logic + +(defun get-paste-contents (id) + "read file lmao. also do some checks. we don't want LFI" + (let ((path (probe-file (concatenate 'string "bin/" id)))) + (if (and path + (not (search "." id)) + (not (search "/" id))) + (uiop:read-file-string path) + "err: bin not found"))) + + + +(defun render-root () + (djula:render-template* + (djula:compile-string *root-template*) + nil)) +(defun render-paste (id) + (djula:render-template* + (djula:compile-string *paste-template*) + nil + :contents (get-paste-contents id) + :link-home *server-external-address* + :link-bin (concatenate 'string *server-external-address* "bin/" id) + :link-raw (concatenate 'string *server-external-address* "raw/" id))) + +(easy-routes:defroute root ("/" :method :get) () + (render-root)) + +(easy-routes:defroute paste ("/bin/:n") () + (render-paste n)) + +(easy-routes:defroute raw ("/raw/:n") () + (get-paste-contents n)) + +;; todo: handle new pastes TODO: doesn't work, fix. +(easy-routes:defroute new ("/" :method :post) (content) + (format t "got somethin: ~a ~%" content)) + + +(defun start-server (&key (port 8080)) + (format t "Starting server on port ~a~%" port) + (force-output) + (setf *server* (make-instance 'easy-routes:easy-routes-acceptor :port port)) + (hunchentoot:start *server*)) +(defun stop-server () + (hunchentoot:stop *server*)) diff --git a/paste.html b/paste.html new file mode 100644 index 0000000..7554f65 --- /dev/null +++ b/paste.html @@ -0,0 +1,47 @@ + +
+{{ contents }}
+ {{ contents }}
+