Compare commits
No commits in common. "e41e0888fa6a2f3ea3208dee9e98c7777583959f" and "747f1305edd64217e90c561e25d76126875f3374" have entirely different histories.
e41e0888fa
...
747f1305ed
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
*~
|
|
||||||
*.fasl
|
|
||||||
bin/*
|
|
91
main.lisp
91
main.lisp
@ -1,91 +0,0 @@
|
|||||||
|
|
||||||
(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/"
|
|
||||||
;;"https://paste.emin.software/"
|
|
||||||
)
|
|
||||||
(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*))
|
|
49
paste.html
49
paste.html
@ -1,49 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title> bin </title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
background-color: #4E5A52;
|
|
||||||
color: #FFFDD0;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
margin: 0;
|
|
||||||
padding: 5px;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
border: 3px solid #FFFDD0;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 80%;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
margin: auto;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
main a {
|
|
||||||
margin-left: 5%;
|
|
||||||
color: #FFFDD0;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
<a href="{{link-home}}"> home </a>
|
|
||||||
<a href="{{link-bin}}"> bin </a>
|
|
||||||
<a href="{{link-raw}}"> raw </a>
|
|
||||||
<br />
|
|
||||||
</main>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<pre><code>{{ contents }}</code></pre>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
53
root.html
53
root.html
@ -1,53 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>lispy pasty thingy</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
background-color: #4E5A52;
|
|
||||||
color: #FFFDD0;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
margin: 0;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
border: 3px solid #FFFDD0;
|
|
||||||
padding: 0px;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 80%;
|
|
||||||
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
form {
|
|
||||||
border: 3px solid #FFFDD0;
|
|
||||||
padding: 2px;
|
|
||||||
margin-top: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 80%;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}*/
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p> This is a simple pastebin-like web app written in Common Lisp.
|
|
||||||
Simply type something into the box below, submit, and share the link
|
|
||||||
with your friends.
|
|
||||||
<br>
|
|
||||||
Pastes are anonymous, no authentication is needed.</p>
|
|
||||||
|
|
||||||
<form method="post" action="/new">
|
|
||||||
<textarea name="content" rows="7" cols="50"></textarea> <br />
|
|
||||||
<input type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
x
Reference in New Issue
Block a user