Tactical commit: I'm fairly sure this is close to good.

This commit is contained in:
Simon Brooke 2020-02-10 21:36:49 +00:00
parent ad5e41c23a
commit 40f4f13667
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
5 changed files with 88 additions and 69 deletions

View file

@ -21,10 +21,10 @@
<th>{{entry.base-name}}</th> <th>{{entry.base-name}}</th>
<td>{{entry.modified}}</td> <td>{{entry.modified}}</td>
<td> <td>
{% if entry.is-image %} ![{{entry.name|capitalize}}](uploads/{{entry.base-name}}) {% else %} [{{entry.name|capitalize}}](uploads/{{entry.base-name}}) {% endif %} {% if entry.is-image %} ![{{entry.name|capitalize}}]({{entry.resource}}) {% else %} [{{entry.name|capitalize}}](uploads/{{entry.resource}}) {% endif %}
</td> </td>
<td> <td>
{% if entry.is-image %} <img src="uploads/{{entry.base-name}}" alt="{{entry.name|capitalize}}"/> {% else %} <a href="uploads/{{entry.base-name}}">link</a> {% endif %} {% if entry.is-image %} <img src="{{entry.resource}}" alt="{{entry.name|capitalize}}"/> {% else %} <a href="{{entry.resource}}">link</a> {% endif %}
</td> </td>
</tr> </tr>

View file

@ -1,22 +1,25 @@
{% extends "templates/base.html" %} {% extends "templates/base.html" %}
{% block content %} {% block content %}
<div id="content" class="auth"> <div id="content" class="auth">
{% if uploaded %} {% if has-uploaded %}
{% if is-image %} {% for upload in uploaded %}
<p> {{upload.filename}}
<img id="uploaded-image" alt="Uploaded image" src="uploads/{{uploaded}}"/> {% if upload.is-image %)
<p>
<img id="uploaded-image" alt="Uploaded image" src="{{upload.resource}}"/>
{% i18n file-upload-link-text %}: {% i18n file-upload-link-text %}:
<code>![Uploaded image](uploads/{{uploaded}})</code> <code>![{{upload.filename}}]({{upload.resource}})</code>
</p> </p>
{% else %} {% else %}
<p> <p>
{% i18n file-upload-link-text %}: {% i18n file-upload-link-text %}:
<code>[Uploaded file](uploads/{{uploaded}})</code> <code>[{{upload.filename}}]({{upload.resource}})</code>
</p> </p>
{% endif %} {% endif %}
{% endfor %}
{% else %} {% else %}
<form action="{{servlet-context}}/upload" enctype="multipart/form-data" method="POST"> <form action="{{servlet-context}}/upload" enctype="multipart/form-data" method="POST">
{% csrf-field %} {% csrf-field %}

View file

@ -4,6 +4,7 @@
(:require [cemerick.url :refer (url url-encode url-decode)] (:require [cemerick.url :refer (url url-encode url-decode)]
[clj-jgit.porcelain :as git] [clj-jgit.porcelain :as git]
[clojure.java.io :as cjio] [clojure.java.io :as cjio]
[clojure.pprint :refer [pprint]]
[clojure.string :as cs] [clojure.string :as cs]
[clojure.walk :refer :all] [clojure.walk :refer :all]
[compojure.core :refer :all] [compojure.core :refer :all]
@ -22,7 +23,7 @@
[smeagol.sanity :refer [show-sanity-check-error]] [smeagol.sanity :refer [show-sanity-check-error]]
[smeagol.util :as util] [smeagol.util :as util]
[smeagol.uploads :as ul] [smeagol.uploads :as ul]
[taoensso.timbre :as timbre] [taoensso.timbre :as log]
[com.stuartsierra.component :as component] [com.stuartsierra.component :as component]
[smeagol.include.resolve-local-file :as resolve] [smeagol.include.resolve-local-file :as resolve]
[smeagol.include :as include])) [smeagol.include :as include]))
@ -54,7 +55,7 @@
"Process `source-text` and save it to the specified `file-path`, committing it "Process `source-text` and save it to the specified `file-path`, committing it
to Git and finally redirecting to wiki-page." to Git and finally redirecting to wiki-page."
[params suffix request] [params suffix request]
(timbre/trace (format "process-source: '%s'" request)) (log/trace (format "process-source: '%s'" request))
(let [source-text (:src params) (let [source-text (:src params)
page (:page params) page (:page params)
file-name (str page suffix) file-name (str page suffix)
@ -64,7 +65,7 @@
user (session/get :user) user (session/get :user)
email (auth/get-email user) email (auth/get-email user)
summary (format "%s: %s" user (or (:summary params) "no summary"))] summary (format "%s: %s" user (or (:summary params) "no summary"))]
(timbre/info (format "Saving %s's changes ('%s') to %s in file '%s'" user summary page file-path)) (log/info (format "Saving %s's changes ('%s') to %s in file '%s'" user summary page file-path))
(spit file-path source-text) (spit file-path source-text)
(git/git-add git-repo file-name) (git/git-add git-repo file-name)
(git/git-commit git-repo summary {:name user :email email}) (git/git-commit git-repo summary {:name user :email email})
@ -94,9 +95,9 @@
user (session/get :user)] user (session/get :user)]
(if-not (if-not
exists? exists?
(timbre/info (log/info
(format "File '%s' not found; creating a new file" file-path)) (format "File '%s' not found; creating a new file" file-path))
(timbre/info (format "Opening '%s' for editing" file-path))) (log/info (format "Opening '%s' for editing" file-path)))
(cond src-text (process-source params suffix request) (cond src-text (process-source params suffix request)
true true
(layout/render template (layout/render template
@ -125,7 +126,7 @@
(defn wiki-page (defn wiki-page
"Render the markdown page specified in this `request`, if any. If none found, redirect to edit-page" "Render the markdown page specified in this `request`, if any. If none found, redirect to edit-page"
[request] [request]
(timbre/trace (format "wiki-page: '%s'" request)) (log/trace (format "wiki-page: '%s'" request))
(or (or
(show-sanity-check-error) (show-sanity-check-error)
(let [params (keywordize-keys (:params request)) (let [params (keywordize-keys (:params request))
@ -135,7 +136,7 @@
exists? (.exists (clojure.java.io/as-file file-path))] exists? (.exists (clojure.java.io/as-file file-path))]
(cond exists? (cond exists?
(do (do
(timbre/info (format "Showing page '%s' from file '%s'" page file-path)) (log/info (format "Showing page '%s' from file '%s'" page file-path))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request) (merge (util/standard-params request)
{:title page {:title page
@ -156,7 +157,7 @@
page (url-decode (or (:page params) (util/get-message :default-page-title request))) page (url-decode (or (:page params) (util/get-message :default-page-title request)))
file-name (str page ".md") file-name (str page ".md")
repo-path util/content-dir] repo-path util/content-dir]
(timbre/info (format "Showing history of page '%s'" page)) (log/info (format "Showing history of page '%s'" page))
(layout/render "history.html" (layout/render "history.html"
(merge (util/standard-params request) (merge (util/standard-params request)
{:title (util/get-message :history-title-prefix request) {:title (util/get-message :history-title-prefix request)
@ -187,10 +188,11 @@
(let (let
[params (keywordize-keys (:params request)) [params (keywordize-keys (:params request))
data-path (str util/content-dir "/uploads/") data-path (str util/content-dir "/uploads/")
cl (count (io/resource-path))
files files
(map (map
#(zipmap #(zipmap
[:base-name :is-image :modified :name] [:base-name :is-image :modified :name :resource]
[(fs/base-name %) [(fs/base-name %)
(if (if
(and (fs/extension %) (and (fs/extension %)
@ -199,11 +201,13 @@
(if (if
(fs/mod-time %) (fs/mod-time %)
(format-instant (fs/mod-time %))) (format-instant (fs/mod-time %)))
(fs/name %)]) (fs/name %)
(subs (str (fs/absolute %)) cl)])
(remove (remove
#(or (cs/starts-with? (fs/name %) ".") #(or (cs/starts-with? (fs/name %) ".")
(fs/directory? %)) (fs/directory? %))
(file-seq (clojure.java.io/file data-path))))] (file-seq (clojure.java.io/file data-path))))]
(log/info (with-out-str (pprint files)))
(layout/render (layout/render
"list-uploads.html" "list-uploads.html"
(merge (util/standard-params request) (merge (util/standard-params request)
@ -236,20 +240,18 @@
uploaded (if upload (ul/store-upload params data-path)) uploaded (if upload (ul/store-upload params data-path))
user (session/get :user) user (session/get :user)
summary (format "%s: %s" user (or (:summary params) "no summary"))] summary (format "%s: %s" user (or (:summary params) "no summary"))]
(if ;; (if
uploaded ;; uploaded
(do ;; (do
(git/git-add git-repo (str data-path (fs/name uploaded))) ;; (map
(git/git-commit git-repo summary {:name user :email (auth/get-email user)}))) ;; #(git/git-add git-repo (str :resource %))
;; uploaded)
;; (git/git-commit git-repo summary {:name user :email (auth/get-email user)})))
(layout/render "upload.html" (layout/render "upload.html"
(merge (util/standard-params request) (merge (util/standard-params request)
{:title (util/get-message :file-upload-title request) {:title (util/get-message :file-upload-title request)
:uploaded (if uploaded (fs/base-name uploaded)) :has-uploaded (not (empty? uploaded))
:is-image (if :uploaded uploaded}))))
uploaded
(image-extns
(cs/lower-case
(fs/extension uploaded))))}))))
(defn version-page (defn version-page
"Render a specific historical version of a page" "Render a specific historical version of a page"
@ -259,7 +261,7 @@
version (:version params) version (:version params)
file-name (str page ".md") file-name (str page ".md")
content (hist/fetch-version util/content-dir file-name version)] content (hist/fetch-version util/content-dir file-name version)]
(timbre/info (format "Showing version '%s' of page '%s'" version page)) (log/info (format "Showing version '%s' of page '%s'" version page))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request) (merge (util/standard-params request)
{:title (str (util/get-message :vers-col-hdr request) " " version " " (util/get-message :of request) " " page) {:title (str (util/get-message :vers-col-hdr request) " " version " " (util/get-message :of request) " " page)
@ -274,7 +276,7 @@
page (url-decode (or (:page params) (util/get-message :default-page-title request))) page (url-decode (or (:page params) (util/get-message :default-page-title request)))
version (:version params) version (:version params)
file-name (str page ".md")] file-name (str page ".md")]
(timbre/info (format "Showing diff between version '%s' of page '%s' and current" version page)) (log/info (format "Showing diff between version '%s' of page '%s' and current" version page))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request) (merge (util/standard-params request)
{:title {:title
@ -303,11 +305,11 @@
action (:action form-params) action (:action form-params)
user (session/get :user) user (session/get :user)
redirect-to (:redirect-to params)] redirect-to (:redirect-to params)]
(if redirect-to (timbre/info (str "After auth, redirect to: " redirect-to))) (if redirect-to (log/info (str "After auth, redirect to: " redirect-to)))
(cond (cond
(= action (util/get-message :logout-label request)) (= action (util/get-message :logout-label request))
(do (do
(timbre/info (str "User " user " logging out")) (log/info (str "User " user " logging out"))
(session/remove! :user) (session/remove! :user)
(response/redirect redirect-to)) (response/redirect redirect-to))
(and username password (auth/authenticate username password)) (and username password (auth/authenticate username password))

View file

@ -6,6 +6,7 @@
[image-resizer.core :refer [resize]] [image-resizer.core :refer [resize]]
[image-resizer.util :refer :all] [image-resizer.util :refer :all]
[me.raynes.fs :as fs] [me.raynes.fs :as fs]
[noir.io :as nio]
[smeagol.configuration :refer [config]] [smeagol.configuration :refer [config]]
[taoensso.timbre :as log]) [taoensso.timbre :as log])
(:import [java.io File] (:import [java.io File]
@ -53,22 +54,26 @@
"Writes img, a RenderedImage, to dest, something that can be turned into "Writes img, a RenderedImage, to dest, something that can be turned into
a file with clojure.java.io/file. a file with clojure.java.io/file.
Takes the following keys as options: Takes the following keys as options:
:format - :gif, :jpg, :png or anything supported by ImageIO :format - :gif, :jpg, :png or anything supported by ImageIO
:quality - for JPEG images, a number between 0 and 100" :quality - for JPEG images, a number between 0 and 100"
[^RenderedImage img dest & {:keys [format quality] :or {format :jpg}}] [^RenderedImage img dest & {:keys [format quality] :or {format :jpg}}]
(if (or (not quality) (not (contains? #{:jpg :jpeg} format))) (log/info "Writing to " dest)
(ImageIO/write img (name format) (io/file dest)) (let [fmt (subs (fs/extension (cs/lower-case dest)) 1)
(let [fmt (rest (fs/extension (cs/lower-case dest))) iw (doto ^ImageWriter (first
iw (doto ^ImageWriter (first (iterator-seq
(iterator-seq (ImageIO/getImageWritersByFormatName
(ImageIO/getImageWritersByFormatName fmt)))
"jpeg"))) (.setOutput (FileImageOutputStream. (io/file dest))))
(.setOutput (FileImageOutputStream. (io/file dest)))) iw-param (doto ^ImageWriteParam (.getDefaultWriteParam iw)
iw-param (doto ^ImageWriteParam (.getDefaultWriteParam iw) (.setCompressionMode ImageWriteParam/MODE_EXPLICIT)
(.setCompressionMode ImageWriteParam/MODE_EXPLICIT) (.setCompressionQuality (float (/ (or quality 75) 100))))
(.setCompressionQuality (float (/ quality 100)))) iio-img (IIOImage. img nil nil)]
iio-img (IIOImage. img nil nil)] (.write iw nil iio-img iw-param)))
(.write iw nil iio-img iw-param))))
(def image?
(memoize
(fn [filename]
(image-file-extns (fs/extension (cs/lower-case (str filename)))))))
(defn auto-thumbnail (defn auto-thumbnail
"For each of the thumbnail sizes in the configuration, create a thumbnail "For each of the thumbnail sizes in the configuration, create a thumbnail
@ -76,19 +81,21 @@
scalable image and is larger than the size." scalable image and is larger than the size."
([^String path ^String filename] ([^String path ^String filename]
(if (if
(image-file-extns (fs/extension (cs/lower-case filename))) (image? filename)
(let [original (buffered-image (.File (str path filename)))] ;; fs/file? (let [original (buffered-image (File. (str path filename)))] ;; fs/file?
(map (map
#(auto-thumbnail path filename % original) #(auto-thumbnail path filename % original)
(keys (config :thumbnails)))) (keys (config :thumbnails))))
(log/info filename " cannot be thumbnailed."))) (log/info filename " cannot be thumbnailed.")))
([^String path ^String filename size ^RenderedImage image] ([^String path ^String filename size ^RenderedImage image]
(let [s (-> config :thumbnails size) (let [s (-> config :thumbnails size)
d (dimensions image)] d (dimensions image)
p (io/file path (name size) filename)]
(if (and (integer? s) (some #(> % s) d)) (if (and (integer? s) (some #(> % s) d))
(do (do
(write-image (resize image s s) (io/file path (name size) filename)) (write-image (resize image s s) p)
(log/info "Created a " size " thumbnail of " filename)) (log/info "Created a " size " thumbnail of " filename)
{:size size :filename filename :location (str p) :is-image true})
(log/info filename "is smaller than " s "x" s " and was not scaled to " size))))) (log/info filename "is smaller than " s "x" s " and was not scaled to " size)))))
(defn store-upload (defn store-upload
@ -108,11 +115,16 @@
(str "store-upload mv file: " tmp-file " to: " path filename)) (str "store-upload mv file: " tmp-file " to: " path filename))
(if tmp-file (if tmp-file
(try (try
(do (let [p (io/file path filename)]
(.renameTo tmp-file (.renameTo tmp-file p)
(File. (str path filename))) ;; TODO: fs/file (remove
(auto-thumbnail path filename) nil?
(File. (str path filename))) (cons
{:size :original
:filename filename
:location (str p)
:is-image (and (image? filename) true)}
(remove nil? (or (auto-thumbnail path filename) '())))))
(catch Exception x (catch Exception x
(log/error (str "Failed to move " tmp-file " to " path filename "; " (type x) ": " (.getMessage x))) (log/error (str "Failed to move " tmp-file " to " path filename "; " (type x) ": " (.getMessage x)))
(throw x))) (throw x)))

View file

@ -3,6 +3,7 @@
smeagol.util smeagol.util
(:require [clojure.java.io :as cjio] (:require [clojure.java.io :as cjio]
[environ.core :refer [env]] [environ.core :refer [env]]
[me.raynes.fs :as fs]
[noir.io :as io] [noir.io :as io]
[noir.session :as session] [noir.session :as session]
[scot.weft.i18n.core :as i18n] [scot.weft.i18n.core :as i18n]
@ -39,10 +40,11 @@
(:start-page config)) (:start-page config))
(def content-dir (def content-dir
(or (str
(:content-dir config) (fs/absolute
(cjio/file (io/resource-path) "content"))) (or
(:content-dir config)
(cjio/file (io/resource-path) "content")))))
(defn standard-params (defn standard-params
"Return a map of standard parameters to pass to the template renderer." "Return a map of standard parameters to pass to the template renderer."