From d64ed75388ccd34e391a09a0e1a31658a8e019e5 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Thu, 1 Aug 2013 01:24:32 +0200 Subject: Initial commit --- hypo.hy | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100755 hypo.hy (limited to 'hypo.hy') diff --git a/hypo.hy b/hypo.hy new file mode 100755 index 0000000..1ebadbb --- /dev/null +++ b/hypo.hy @@ -0,0 +1,135 @@ +#!/usr/bin/env hy +;; Hypo -- Sharing is caring. +;; 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 . + +(import web sys os hashlib datetime + [pygments [highlight]] + [pygments.lexers [guess-lexer-for-filename]] + [pygments.formatters [HtmlFormatter]]) + +(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/")) +(def urls (, "/raw/(.*)" "raw" + "/dl/(.*)" "download" + "/([a-f0-9]{7})$" "html" + "/(.*)" "upload")) +(def db + (kwapply (web.database) + {"dbn" "postgres" "user" *dbuser* "pw" *dbpw* "db" *dbname*})) + +(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"))) + +(defun read-file [filename] + (let (res) + (with [f (file filename "r")] + (setv res (f.read))) + res)) + +(defun no-such-file [] + (setv web.ctx.status "404 Not Found") + "No such file.\n") + +(defun get-file [name] + (let ((res (kwapply (db.select "hfile" {"shash" name}) + {"where" "shash = $shash"}))) + (if res (car res)))) + +(defclass raw [] + [[GET (lambda [self name] + (let ((filename (+ "files/" name)) + (resp (if (os.path.exists filename) + (read-file filename)))) + (or resp (no-such-file))))]]) + +(defclass download [] + [[GET (lambda [self name] + (let ((hfile (get-file name)) + (filename (+ "files/" name))) + (if (and hfile (os.path.exists filename)) + (progn + (web.header "Content-Disposition" + (+ "attachment; filename=\"" + hfile.filename "\"")) + (read-file filename)) + (no-such-file))))]]) + +(defclass html [] + [[GET (lambda [self name] + (let ((hfile (get-file name)) + (filename (+ "files/" name))) + (if (and hfile (os.path.exists filename)) + (cond + ((= hfile.type "text") + (progn + (let ((content (read-file filename)) + (lexer (guess-lexer-for-filename + hfile.filename content)) + (formatter (HtmlFormatter))) + (kwapply (render.main) + {"content" (highlight content lexer + formatter) + "style" (formatter.get-style-defs + ".highlight") + "file" hfile}) + ))) + ((= hfile.type "image") + (kwapply (render.main) + {"content" (kwapply (render.image) + {"name" name}) + "style" "" + "file" hfile}))) + (no-such-file))))] + + [DELETE (lambda [self name] + (let ((filename (+ "files/" name))) + (kwapply (db.delete "hfile") + {"where" (+ "shash = '" name "'")}) + (if (os.path.exists filename) + (os.remove filename) + (no-such-file))))]]) + +(defclass upload [] + [[PUT (lambda [self name] + (let ((h (hashes name))) + (with [f (file (+ "files/" (get h 0)) "w")] + (.write f (web.data))) + (kwapply (db.insert "hfile") + {"shash" (get h 0) + "hash" (get h 1) + "filename" name + "type" (get-type (get (os.path.splitext name) 1))}) + (setv web.ctx.status "201 Created") + (+ web.ctx.home "/" (get h 0) "\n")))]]) + +(when (= __name__ "__main__") + (let ((sys.argv (slice sys.argv 1)) + (app (web.application urls (globals)))) + (.run app))) -- cgit v1.2.3-54-g00ecf