001  (ns ^{:doc "Utility functions used by other namespaces in this package."
002        :author "Simon Brooke"}
003   mw-ui.util
004    (:require [clojure.java.io :refer [file]]
005              [clojure.string :refer [starts-with?]]
006              [markdown.core :as md]
007              [noir.io :as io]
008              [noir.session :as session]
009              [taoensso.timbre :as timbre]))
010  
011  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
012  ;;;;
013  ;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
014  ;;;;
015  ;;;; This program is free software; you can redistribute it and/or
016  ;;;; modify it under the terms of the GNU General Public License
017  ;;;; as published by the Free Software Foundation; either version 2
018  ;;;; of the License, or (at your option) any later version.
019  ;;;;
020  ;;;; This program is distributed in the hope that it will be useful,
021  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
022  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023  ;;;; GNU General Public License for more details.
024  ;;;;
025  ;;;; You should have received a copy of the GNU General Public License
026  ;;;; along with this program; if not, write to the Free Software
027  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
028  ;;;; USA.
029  ;;;;
030  ;;;; Copyright (C) 2014 Simon Brooke
031  ;;;;
032  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
033  
034  (def running-from-filesystem 
035    "We assume we're running from the filesystem unless we find we're not."
036    (atom true))
037  
038  
039  (def compile-time-resources
040    "The resources which were visible at compile time. If we are running from
041     a JAR file, it is highly likely that these are all the resources available
042     at run time."
043    (let [f (file "resources/public")
044          n (count (.getCanonicalPath f))]
045      (remove nil?
046              (map #(let [s (.getCanonicalPath %)]
047                      (when (> (count s) n)
048                        (subs s n)))
049                   (file-seq f)))))
050  
051  
052  (defn md->html
053    "reads a markdown file from public/md and returns an HTML string"
054    [filename]
055    (->>
056     (io/slurp-resource filename)
057     (md/md-to-html-string)))
058  
059  
060  (defn cache-seq-match
061    "Do the same processing that list-resources does on names fetched from
062     the file system, except on the resource list cached at compile time."
063    [path pattern]
064    (timbre/info compile-time-resources)
065    (let [n (count path)]
066      (remove nil?
067              (map #(when (> (count %) n)
068                      (let [name (subs % n)]
069                        (last (re-matches pattern name))))
070                  (filter #(starts-with? % path) 
071                           compile-time-resources)))))
072  
073  
074  (defn list-resources
075    "List resource files matching `pattern` in `directory`."
076    [directory pattern]
077    (let
078     [path (str (io/resource-path) directory)]
079      (session/put! :list-resources-path path)
080      (try
081        (sort
082         (remove nil?
083                 (if @running-from-filesystem
084                   (map #(first (rest (re-matches pattern (.getName %))))
085                        (file-seq (file path)))
086                   (cache-seq-match directory pattern))))
087        (catch Exception any
088          (timbre/log (str "Not running from filesystem?"
089                           (.getName (.getClass any))))
090          (reset! running-from-filesystem false)
091          (cache-seq-match directory pattern)))))