Sort of works, well enough to know that the concept is valid.

NOT NEARLY good enough to release!
This commit is contained in:
Simon Brooke 2020-02-26 13:58:01 +00:00
parent 5a784f4497
commit 80bc1e071b
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
7 changed files with 176 additions and 47 deletions

View file

@ -45,7 +45,7 @@
:remote "https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"}}
:styles {:leaflet {:local "vendor/node_modules/leaflet/dist/leaflet.css"
:remote "https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"}}
:icon-url-base "uploads/map-pin/"}
:icon-url-base "map-pin/"}
:mermaid {:formatter "smeagol.extensions.mermaid/process-mermaid"
:scripts {:core {:local "vendor/node_modules/mermaid/dist/mermaid.min.js"
:remote "https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.4.6/mermaid.min.js"}}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

139
src/smeagol/finder.clj Normal file
View file

@ -0,0 +1,139 @@
(ns ^{:doc "Find (by doing a 302 redirect to) appropriate files; if no
appropriate file is found return a 302 redirect to a default file."
:author "Simon Brooke"}
smeagol.finder
(:require [clojure.string :as cs]
[me.raynes.fs :as fs]
[noir.io :as io]
[noir.response :as response]
[smeagol.configuration :refer [config]]
[smeagol.util :refer [local-url-base content-dir]]
[taoensso.timbre :as log]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; Smeagol: a very simple Wiki engine.
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
;;;; as published by the Free Software Foundation; either version 2
;;;; of the License, or (at your option) any later version.
;;;;
;;;; This program 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 General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
;;;; USA.
;;;;
;;;; Copyright (C) 2017 Simon Brooke
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; See:
;; https://github.com/weavejester/compojure/wiki/Routes-In-Detail
;; https://github.com/weavejester/compojure/wiki/Destructuring-Syntax
(defn to-url
"Given the absolute file path `fqn`, return the relative URL to that path
within Smeagol, if any, else `nil`."
[fqn]
(let [f (when fqn (str fqn))
l (str local-url-base)
c (str content-dir)]
(cond
(nil? f) nil
(cs/starts-with? f l) (subs f (count l))
;; content-dir may not be within local-url-base
;; TODO: potential bad bug: check that when uploads isn't within local-url-base
;; the right copies of files are actually getting served!
(cs/starts-with? f c) (str "content/" (subs f (count c))))))
(defn find-file-on-path
"Find a file with a name like this `n` on this `path` with
one of these `extensions`. Question: should we recurse down
the hierarchy?"
[n path extensions]
(let [ext (fs/extension n)
basename (subs n 0 (- (count n) (count ext)))
fqn (fs/absolute (fs/file path n))]
(if (and (fs/exists? fqn) (fs/readable? fqn))
fqn
(first
(remove
nil?
(map
#(let [fqn' (fs/absolute (fs/file path (str basename %)))]
(when (and (fs/exists? fqn') (fs/readable? fqn'))
fqn'))
extensions))))))
(defn find-file-on-paths
"Find a file with a name like this `n` on one of these `paths` with
one of these `extensions`"
[n paths extensions]
(first
(remove
nil?
(map
#(find-file-on-path n % extensions)
paths))))
(defn find-image-url
"Return a 302 redirect to
1. The requested file, if available;
2. This default URL otherwise."
[request requested-name default-url paths]
(let [url (to-url
(find-file-on-paths requested-name paths
[".gif" ".png" ".jpg" ".jpeg" ".svg"]))]
(if url
(log/info "Found image" requested-name "at" url)
(log/warn "Failed to find image matching" requested-name))
(response/redirect
;; (str "/" (:servlet-context request) url) ;; TODO: >>> Nasty
(if url
(str (name (:scheme request)) "://" (:host request) ":" (:server-port request) "/" url)
default-url)
:found )))
;; (def r {:ssl-client-cert nil,
;; :access-rules [{:redirect "/auth",
;; :rule #object[smeagol.handler$user_access 0x7ee9346 "smeagol.handler$user_access@7ee9346"]}],
;; :protocol "HTTP/1.1",
;; :cookies {"ring-session" {:value "4e7c059e-2796-44a0-b03a-c712dae43588"}},
;; :remote-addr "127.0.0.1",
;; :params {:n "froboz"},
;; :flash nil,
;; :route-params {:n "froboz"},
;; :headers {"cookie" "ring-session=4e7c059e-2796-44a0-b03a-c712dae43588",
;; "accept" "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
;; "upgrade-insecure-requests" "1", "user-agent" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0",
;; "connection" "keep-alive",
;; "host" "localhost:3000",
;; "accept-language" "en-GB,en;q=0.7,en-US;q=0.3",
;; "accept-encoding" "gzip, deflate",
;; "dnt" "1"},
;; :server-port 3000,
;; :content-length nil,
;; :form-params {},
;; :session/key "4e7c059e-2796-44a0-b03a-c712dae43588",
;; :query-params {},
;; :content-type nil,
;; :character-encoding nil,
;; :uri "/map-pin/froboz",
;; :server-name "localhost",
;; :query-string nil,
;; :body #object[org.eclipse.jetty.server.HttpInputOverHTTP 0x5abc1216 "HttpInputOverHTTP@5abc1216"],
;; :multipart-params {},
;; :scheme :http,
;; :request-method :get,
;; :session {:ring.middleware.anti-forgery/anti-forgery-token "2HVXUnBfpuw6kpLTWXTbiSk4zQN5/qPfvJtI/rw5Ju+m/f5I4r5nsOeEr1tuS5YWrXlNRWO6ruX/MHl4",
;; :ring.middleware.session-timeout/idle-timeout 1582725564}}

View file

@ -1,44 +0,0 @@
(ns ^{:doc "Find (by doing a 302 redirect to) appropriate images; if no
appropriate image is found return a 302 redirect to a default image."
:author "Simon Brooke"}
smeagol.uploads
(:require [clojure.string :as cs]
[me.raynes.fs :as fs]
[noir.io :as nio]
[noir.response :as response]
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; Smeagol: a very simple Wiki engine.
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
;;;; as published by the Free Software Foundation; either version 2
;;;; of the License, or (at your option) any later version.
;;;;
;;;; This program 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 General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
;;;; USA.
;;;;
;;;; Copyright (C) 2017 Simon Brooke
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; See:
;; https://github.com/weavejester/compojure/wiki/Routes-In-Detail
;; https://github.com/weavejester/compojure/wiki/Destructuring-Syntax
(defn find-image
"Return a 302 redirect to
1. The requested file, if available;
2. This default URL otherwise."
[request requested-name default-url paths-to-explore]
(let [url (do-something-to-find-appropriate-file request)]
(response/redirect url :found )))

View file

@ -18,6 +18,7 @@
[smeagol.authenticate :as auth]
[smeagol.configuration :refer [config]]
[smeagol.diff2html :as d2h]
[smeagol.finder :refer [find-image-url]]
[smeagol.formatting :refer [md->html]]
[smeagol.history :as hist]
[smeagol.layout :as layout]
@ -31,7 +32,7 @@
[smeagol.configuration :refer [config]]
[smeagol.include.resolve-local-file :as resolve]
[smeagol.include :as include]
[smeagol.util :refer [content-dir local-url]]))
[smeagol.util :refer [content-dir local-url local-url-base upload-dir]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -466,12 +467,39 @@
(GET "/edit-user" request (route/restricted (admin/edit-user request)))
(POST "/edit-user" request (route/restricted (admin/edit-user request)))
(GET "/history" request (history-page request))
(GET "/image/:n" request (find-image-url
request
(-> request :route-params :n)
"http://localhost:3000/img/smeagol.png"
[(fs/file local-url-base "img")
upload-dir
;; TODO: should map over the configured
;; thumbnail paths in descending order
;; by size - generally, bigger images are
;; better.
(fs/file upload-dir "med")
(fs/file upload-dir "small")
(fs/file upload-dir "map-pin")]))
(GET "/list-uploads" request (route/restricted (list-uploads-page request)))
(POST "/list-uploads" request (route/restricted (list-uploads-page request)))
(GET "/version" request (version-page request))
(GET "/map-pin/:n" request (find-image-url
request
(-> request :route-params :n)
"http://localhost:3000/img/Unknown-pin.png"
[(fs/file local-url-base "img")
;; TODO: should map over the configured
;; thumbnail paths in ascending order
;; by size - for map pins, smaller images are
;; better.
(fs/file upload-dir "map-pin")
(fs/file upload-dir "small")
(fs/file upload-dir "med")
upload-dir
local-url-base]))
(GET "/passwd" request (passwd-page request))
(POST "/passwd" request (passwd-page request))
(GET "/upload" request (route/restricted (upload-page request)))
(POST "/upload" request (route/restricted (upload-page request)))
(GET "/version" request (version-page request))
(GET "/wiki" request (wiki-page request))
)

View file

@ -61,6 +61,12 @@
(let [a (str (fs/absolute content-dir))]
(subs a 0 (- (count a) (count "content")))))
;; (def local-url-base
;; "Essentially, the slash-terminated absolute path of the `public` resource
;; directory. **NOTE** that this MAY NOT contain `content-dir`."
;; (cjio/file (io/resource-path)))
(defn not-servable-reason
"As a string, the reason this `file-path` cannot safely be served, or `nil`
if it is safe to serve. This reason may be logged, but should *not* be