First working version, yay

This commit is contained in:
Aaron Fischer 2017-03-15 00:28:27 +01:00
parent d446a0e6e6
commit 9e8af48b88
15 changed files with 165 additions and 152 deletions

View file

@ -15,4 +15,7 @@
(stop)
(start))
(defn start-with-server []
(start)
(mount/start #'yenu.core/http-server))

View file

@ -1,7 +1,6 @@
(defproject yenu "0.1.0-SNAPSHOT"
:description "yenu -- The image sharing tool for friends"
:url "http://example.com/FIXME"
:url "https://aaron-fischer.net/"
:dependencies [[bouncer "1.0.0"]
[cljs-ajax "0.5.8"]
@ -11,7 +10,6 @@
[luminus-immutant "0.2.3"]
[luminus-migrations "0.2.9"]
[luminus-nrepl "0.1.4"]
[markdown-clj "0.9.94"]
[metosin/ring-http-response "0.8.1"]
[mount "0.1.11"]
[org.clojure/clojure "1.8.0"]

View file

@ -1,4 +1,9 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100%;
padding-top: 40px; }
#images {
margin: auto;
}
.thumbnail-image {
margin: 2px;
padding: 1px;
border: 1px solid #ddd;
}

View file

@ -0,0 +1,37 @@
{% extends "layout.html" %}
{% block content %}
<h2>Upload a new image</h2>
<p>Here you can upload a new image to the gallery. This image is then saved in
three different formats. The raw image, a scaled down version and a scoped
thumbnail image for the overview. You can upload all sorts of images.</p>
<form action="/upload" enctype="multipart/form-data" method="POST" class="form-horizontal">
{% csrf-field %}
<div class="form-group">
<label for="file" class="sr-only">Image</label>
<input id="file" class="form-control" name="file" type="file" />
</div>
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" placeholder="Default is the image name">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea name="description" class="form-control" rows="4" placeholder="Optional"></textarea>
</div>
<div class="form-group">
<label for="tags">Tags</label>
<input type="text" id="tags" name="tags" class="form-control" placeholder="Separate the tags with space(s) or comma">
</div>
<button type="submit" class="btn btn-success">
<span class="fa fa-floppy-o"></span>
Upload image
</button>
</form>
{% endblock %}

View file

@ -1,56 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Something bad happened</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% style "/assets/bootstrap/css/bootstrap.min.css" %}
{% style "/assets/bootstrap/css/bootstrap-theme.min.css" %}
<style type="text/css">
html {
height: 100%;
min-height: 100%;
min-width: 100%;
overflow: hidden;
width: 100%;
}
html body {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
html .container-fluid {
display: table;
height: 100%;
padding: 0;
width: 100%;
}
html .row-fluid {
display: table-cell;
height: 100%;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="col-lg-12">
<div class="centering text-center">
<div class="text-center">
<h1><span class="text-danger">Error: {{status}}</span></h1>
<hr>
{% if title %}
<h2 class="without-margin">{{title}}</h2>
{% endif %}
{% if message %}
<h4 class="text-danger">{{message}}</h4>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</body>
</html>
{% extends "layout.html" %}
{% block content %}
<h1><span class="text-danger">Error: {{status}}</span></h1>
<hr>
{% if title %}
<h2 class="without-margin">{{title}}</h2>
{% endif %}
{% if message %}
<h4 class="text-danger">{{message}}</h4>
{% endif %}
{% endblock %}

View file

@ -1,46 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to yenu</title>
</head>
<body>
<div id="navbar"></div>
<div id="app">
<div class="container-fluid">
<div class="card-deck">
<div class="card-block">
<h4>Welcome to yenu</h4>
<p>If you're seeing this message, that means you haven't yet compiled your ClojureScript!</p>
<p>Please run <code>lein figwheel</code> to start the ClojureScript compiler and reload the page.</p>
<h4>For better ClojureScript development experience in Chrome follow these steps:</h4>
<ul>
<li>Open DevTools
<li>Go to Settings ("three dots" icon in the upper right corner of DevTools > Menu > Settings F1 > General > Console)
<li>Check-in "Enable custom formatters"
<li>Close DevTools
<li>Open DevTools
</ul>
<p>See <a href="http://www.luminusweb.net/docs/clojurescript.md">ClojureScript</a> documentation for further details.</p>
</div>
</div>
</div>
</div>
<!-- scripts and styles -->
{% style "/assets/bootstrap/css/bootstrap.min.css" %}
{% style "/assets/font-awesome/css/font-awesome.min.css" %}
{% style "/css/screen.css" %}
<script type="text/javascript">
var context = "{{servlet-context}}";
var csrfToken = "{{csrf-token}}";
</script>
{% script "/js/app.js" %}
</body>
</html>

View file

@ -0,0 +1,16 @@
{% extends "layout.html" %}
{% block content %}
<div id="iamges">
{% for image in images %}
<div class="thumbnail-image pull-left">
<a href="/show/{{ image.hash }}">
<img src="/images/thumbnails/{{ image.hash }}.png" alt="{{ image.title }}">
<p>{{ image.title }}
</a>
</div>
{% endfor %}
</div>
<div class="clearfix"></div>
{% endblock %}

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>yenu -- the image sharing tool for friends</title>
</head>
<body>
<div id="content" class="col-md-12">
<h1>yenu</h1>
<a href="/" class="">Images</a>,
<a href="/upload" class="">Upload a new image</a>
<hr>
{% block content %}
{% endblock %}
</div>
<!-- cljs stuff, remove ore reuse it (see cljs/jenu/core.cljs) -->
<div id="navbar"></div>
<div id="app"></div>
{% style "/assets/bootstrap/css/bootstrap.min.css" %}
{% style "/assets/font-awesome/css/font-awesome.min.css" %}
{% style "/css/screen.css" %}
<script type="text/javascript">
var context = "{{servlet-context}}";
var csrfToken = "{{csrf-token}}";
</script>
{% script "/js/app.js" %}
</body>
</html>

View file

@ -1,9 +0,0 @@
<h2>Upload image</h2>
<form action="/upload" enctype="multipart/form-data" method="POST">
{% csrf-field %}
<input id="file" name="file" type="file" />
<input type="text" name="title">
<textarea name="description"></textarea>
<input type="text" name="tags">
<input type="submit" value="upload" />
</form>

View file

@ -1,7 +1,8 @@
(ns yenu.handler
(:require [compojure.core :refer [routes wrap-routes]]
[yenu.layout :refer [error-page]]
[yenu.routes.home :refer [home-routes upload-routes]]
[yenu.routes.core :refer [core-routes]]
[yenu.routes.admin :refer [admin-routes]]
[compojure.route :as route]
[yenu.env :refer [defaults]]
[mount.core :as mount]
@ -13,10 +14,10 @@
(def app-routes
(routes
(-> #'home-routes
(-> #'core-routes
(wrap-routes middleware/wrap-csrf)
(wrap-routes middleware/wrap-formats))
(-> #'upload-routes
(-> #'admin-routes
(wrap-routes middleware/wrap-csrf)
(wrap-routes middleware/wrap-formats))
(route/not-found

View file

@ -54,7 +54,8 @@
(defn scale-image-and-save [filepath]
(let [image-hash (target-image-filename filepath)
file-extension (fs/extension filepath)
new-file-name (str image-hash file-extension)]
new-raw-file-name (str image-hash file-extension)
new-file-name (str image-hash ".png")]
(fs/copy filepath (data-path "gallery" "raw" new-file-name))
(save scale-normal [1024 768] filepath (data-path "gallery" "normal" new-file-name))
(save scale-thumbnail [250] filepath (data-path "gallery" "thumbnails" new-file-name))

View file

@ -1,28 +1,26 @@
(ns yenu.layout
(:require [selmer.parser :as parser]
[selmer.filters :as filters]
[markdown.core :refer [md-to-html-string]]
[ring.util.http-response :refer [content-type ok]]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[yenu.helpers.images :as image-helper]
[ring.middleware.anti-forgery :refer [*anti-forgery-token*]]))
(declare ^:dynamic *app-context*)
(parser/set-resource-path! (clojure.java.io/resource "templates"))
(parser/add-tag! :csrf-field (fn [_ _] (anti-forgery-field)))
(filters/add-filter! :markdown (fn [content] [:safe (md-to-html-string content)]))
(defn render
"renders the HTML template located relative to resources/templates"
[template & [params]]
(content-type
(ok
(parser/render-file
template
(assoc params
:page template
:csrf-token *anti-forgery-token*
:servlet-context *app-context*)))
"text/html; charset=utf-8"))
(ok
(parser/render-file
template
(assoc params
:page template
:csrf-token *anti-forgery-token*
:servlet-context *app-context*)))
"text/html; charset=utf-8"))
(defn error-page
"error-details should be a map containing the following keys:

View file

@ -1,4 +1,4 @@
(ns yenu.routes.home
(ns yenu.routes.admin
(:require [yenu.layout :as layout]
[compojure.core :refer [defroutes GET POST]]
[ring.util.http-response :as response]
@ -28,25 +28,17 @@
(let [{tag-id :id} (db/get-tag {:tagname tag})]
(db/add-tag-to-image! {:imageid image-id :tagid tag-id})))
(defn add-to-database [filehash title description tags]
(defn add-image-to-database [filehash title description tags]
(let [img (db/create-image! {:hash filehash :title title :description description})
image-id ((keyword "last_insert_rowid()") img)
all-tags (str/split tags, #"(\s*,\s*|\s+)")]
(map #(add-tag image-id %) all-tags)))
(defroutes upload-routes
(defroutes admin-routes
(GET "/upload" []
(layout/render "upload.html"))
(layout/render "admin/upload.html"))
(POST "/upload" [file title description tags]
(-> (upload-file file)
(images/process-image)
(add-to-database title description tags))
(add-image-to-database title description tags))
(redirect "/")))
(defroutes home-routes
(GET "/" []
(layout/render "home.html"))
(GET "/docs" []
(-> (response/ok (-> "docs/docs.md" io/resource slurp))
(response/header "Content-Type" "text/plain; charset=utf-8"))))

View file

@ -0,0 +1,27 @@
(ns yenu.routes.core
(:require [yenu.layout :as layout]
[compojure.core :refer [defroutes GET POST]]
[ring.util.http-response :as response]
[ring.util.response :refer [redirect file-response]]
[yenu.helpers.images :as images]
[yenu.db.core :as db]))
(defn index-page []
(layout/render "index.html"
{:images (db/get-all-images {:offset 0 :count 10})}))
(defn image-file [type hash ext]
(let [filename (str hash "." ext)]
(file-response (images/data-path "gallery" type filename))))
(defroutes core-routes
(GET "/" []
(index-page))
(GET ["/images/:type/:hash.:ext"
;;:type #"(normal|raw|thumbnails)"
;;:hash #"[0-9]+-[^.]+"
;;:ext #"(png|jpg)"
]
[type hash ext]
(image-file type hash ext)))

View file

@ -4,7 +4,6 @@
[secretary.core :as secretary :include-macros true]
[goog.events :as events]
[goog.history.EventType :as HistoryEventType]
[markdown.core :refer [md->html]]
[yenu.ajax :refer [load-interceptors!]]
[ajax.core :refer [GET POST]])
(:import goog.History))
@ -40,7 +39,7 @@
(when-let [docs (session/get :docs)]
[:div.row>div.col-sm-12
[:div {:dangerouslySetInnerHTML
{:__html (md->html docs)}}]])])
{:__html "test"}}]])])
(def pages
{:home #'home-page
@ -80,7 +79,8 @@
(r/render [#'page] (.getElementById js/document "app")))
(defn init! []
(load-interceptors!)
(fetch-docs!)
(hook-browser-navigation!)
(mount-components))
;; (load-interceptors!)
;; (fetch-docs!)
;; (hook-browser-navigation!)
;; (mount-components)
)