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