mirror of
https://github.com/journeyman-cc/smeagol.git
synced 2026-04-12 18:05:06 +00:00
Tactical commit: I'm fairly sure this is close to good.
This commit is contained in:
parent
ad5e41c23a
commit
40f4f13667
5 changed files with 88 additions and 69 deletions
|
|
@ -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 %}  {% else %} [{{entry.name|capitalize}}](uploads/{{entry.base-name}}) {% endif %}
|
{% if entry.is-image %}  {% 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>
|
||||||
|
|
|
||||||
|
|
@ -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 %}
|
||||||
|
{{upload.filename}}
|
||||||
|
{% if upload.is-image %)
|
||||||
<p>
|
<p>
|
||||||
<img id="uploaded-image" alt="Uploaded image" src="uploads/{{uploaded}}"/>
|
<img id="uploaded-image" alt="Uploaded image" src="{{upload.resource}}"/>
|
||||||
|
|
||||||
{% i18n file-upload-link-text %}:
|
{% i18n file-upload-link-text %}:
|
||||||
|
|
||||||
<code></code>
|
<code></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 %}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
@ -56,19 +57,23 @@
|
||||||
: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
|
||||||
"jpeg")))
|
fmt)))
|
||||||
(.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 (/ quality 100))))
|
(.setCompressionQuality (float (/ (or quality 75) 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)))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
(str
|
||||||
|
(fs/absolute
|
||||||
(or
|
(or
|
||||||
(:content-dir config)
|
(:content-dir config)
|
||||||
(cjio/file (io/resource-path) "content")))
|
(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."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue