hypo/hypo.hy

159 lines
5.1 KiB
Hy
Raw Normal View History

2013-08-01 01:24:32 +02:00
#!/usr/bin/env hy
2013-08-11 00:16:26 +02:00
;; Hypo -- Quickly share stuff
2013-08-01 01:24:32 +02:00
;; Copyright (C) 2013 Tom Willemse
;; Hypo is free software: you can redistribute it and/or modify it
;; under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;; Hypo is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
;; Public License for more details.
;; You should have received a copy of the GNU Affero General Public
;; License along with Hypo. If not, see <http://www.gnu.org/licenses/>.
(import web sys os hashlib datetime shutil
2013-08-01 01:24:32 +02:00
[pygments [highlight]]
[pygments.lexers [get-lexer-by-name guess-lexer-for-filename]]
[pygments.formatters [HtmlFormatter]]
[pygments.util [ClassNotFound]]
[gittle [Gittle]])
2013-08-01 01:24:32 +02:00
(try (import [config [*]])
(catch [ImportError]
(print "Please copy the config.example.hy to config.hy and set"
"the values to your preference.")
(sys.exit 1)))
(def render (web.template.render "templates/"))
2013-08-25 23:21:39 +02:00
(def urls (, (+ "/" *prefix*) "index"
(+ "/" *prefix* "raw/(.*)") "raw"
(+ "/" *prefix* "dl/(.*)") "download"
(+ "/" *prefix* "([a-f0-9]{7})$") "html"
(+ "/" *prefix* "(.*)") "upload"))
2013-08-01 01:24:32 +02:00
(defun hashes [name]
(let ((hasher (hashlib.sha1)))
(hasher.update name)
(hasher.update (str (datetime.datetime.now)))
(let ((digest (hasher.hexdigest)))
(, (slice digest 0 7) digest))))
(defun get-type [ext]
(cond
[(in ext (, ".jpg" ".jpeg" ".png" ".gif")) "image"]
[True "text"]))
2013-08-01 01:24:32 +02:00
(defun read-file [filename]
(let (res)
(with [[f (file filename "r")]]
2013-08-01 01:24:32 +02:00
(setv res (f.read)))
res))
(defun no-such-file []
(setv web.ctx.status (str "404 Not Found"))
2014-02-19 01:35:59 +01:00
(render.notfound))
2013-08-01 01:24:32 +02:00
(defun get-lexer [filename content]
"Try to guess the correct lexer by FILENAME and CONTENT.
If no lexer is found fallback onto the text lexer."
(try (guess-lexer-for-filename filename content)
(catch [ClassNotFound]
(get-lexer-by-name "text"))))
(defun get-raw [self name]
(let ((dirname (+ "files/" (os.path.dirname name)))
(repo (and (os.path.exists dirname)
(Gittle dirname)))
(resp (if repo
(get (.commit-file repo "HEAD" (os.path.basename name))
"data"))))
(or resp (no-such-file))))
(defun get-attachment [self name]
(let ((dirname (+ "files/" (os.path.dirname name)))
(repo (and (os.path.exists dirname)
(Gittle dirname))))
(if repo
(progn
(web.header "Content-Disposition"
(+ "attachment; filename=\"" name "\""))
(get (.commit-file repo "HEAD" (os.path.basename name)) "data"))
(no-such-file))))
2013-08-01 01:24:32 +02:00
(defun render-file [hash repo ref filename]
(if (not (os.path.isdir filename))
(let ((content (get (.commit-file repo ref filename) "data"))
(lexer (get-lexer filename content))
(formatter (HtmlFormatter))
2014-07-25 22:27:41 +02:00
(kwargs {"file" filename "hash" hash}))
(.update
2014-07-25 22:27:41 +02:00
kwargs (if (in (get (os.path.splitext filename) 1)
[".png" ".jpg" ".jpeg" ".gif"])
2014-07-25 22:27:41 +02:00
{"content" (apply render.image []
{"name" filename
"hash" hash})
"style" ""}
{"content" (highlight content lexer formatter)
"style" (formatter.get-style-defs ".highlight")}))
2014-07-25 22:27:41 +02:00
(apply render.main [] kwargs))
""))
(defun get-html [self name]
(let ((dirname (+ "files/" name))
(repo (and (os.path.exists dirname)
(Gittle dirname))))
(if repo
(car (list-comp (render-file name repo "HEAD" f)
[f (.iterkeys (.commit-tree repo "HEAD"))]
(not (or (= f ".")
(= f "..")))))
(no-such-file))))
(defun delete-dir [self name]
(let ((dirname (+ "files/" name)))
(if (os.path.exists dirname)
2014-02-19 01:02:21 +01:00
(do (shutil.rmtree dirname)
2014-04-23 23:16:38 +02:00
(+ "Successfully removed " name "\n"))
(no-such-file))))
(defun upload-file [self name]
(let ((h (hashes name))
(dirname (+ "files/" (get h 0))))
(os.mkdir dirname)
(with [[f (file (+ dirname "/" name) "w")]]
(.write f (web.data)))
(let ((repo (Gittle.init dirname)))
(.stage repo [(str name)])
2014-07-25 22:27:41 +02:00
(apply repo.commit []
{"name" "Hypo"
"email" "hypo@ryuslash.org"
"message" "Initial commit"}))
(setv web.ctx.status (str "201 Created"))
(+ web.ctx.home "/" *prefix* (get h 0) "\n")))
(defclass raw []
[[GET get-raw]])
(defclass download []
[[GET get-attachment]])
2013-08-01 01:24:32 +02:00
(defclass html []
[[GET get-html]
[DELETE delete-dir]])
2013-08-01 01:24:32 +02:00
(defclass upload []
[[PUT upload-file]])
2013-08-01 01:24:32 +02:00
2013-08-25 23:21:39 +02:00
(defclass index []
[[GET (lambda [self] (render.index))]])
(defun hypo-start [argv]
(let ((sys.argv argv)
2013-08-01 01:24:32 +02:00
(app (web.application urls (globals))))
(.run app)))