     (list item)
     (flatten (map flat-coll (if-not (map? item) item (ordered-map-values item))))))
 
-
 (defn map-sha256
   "Calculates SHA-256 hex digest of (ordered) content in a collection"
   [coll]
   (hex-digest "SHA-256" (apply str (flat-coll coll))))
 
 (defn file-extension [filename]
-  (last (str/split (str filename) #"\.")))
+  (let [ext (last (str/split (str filename) #"\."))]
+    (if ext (str "." ext))))
+
+(defn public-path-from-content
+  [content extension]
+  (let [checksum (hex-digest "SHA-256" content)]
+    (apply str (concat (list "file/")
+                       (interpose "/" (take 4 (char-array checksum)))
+                       (list "/" checksum extension)))))
 
 (defn public-path
   "Calculate checksum for file and use it as a filename under public dir"
   ([filename] (public-path filename (file-extension filename)))
   ([filename extension]
-   (let [content (slurp filename)
-         checksum (hex-digest "SHA-256" content)]
-     (apply str (concat (list "file/")
-                        (interpose "/" (take 4 (char-array checksum)))
-                        (list "/" checksum "." extension))))))
+    (let [content (slurp filename)]
+      (public-path-from-content content extension))))
 
 (defn fetch-file-content [url]
   "Fetch file content from url"

    (subs path 0 (.lastIndexOf path "?"))
    path))

(defn file-from-url
  [url]
  (if (re-find #"https?" (str url))
    (let [content (fetch-file-content url)
          path (public-path url)
          fname (trim-path path)
          data-dir (get config :data-dir)
          fullpath (str data-dir "/" fname)]
      (try+
        (if-not (.exists (io/as-file data-dir))
          (throw+ "Data directry does not exist"))
        (do
          (io/make-parents fullpath)
          (with-open [w (io/output-stream fullpath)]
            (.write w content))
          fname)
        (catch Object _
          (throw+ "Error copying file: " _))))
    (throw+ "Error in file url: " url)))
  (:require [clojure.java.io :as io]
            [clojure.string :as str]
            [slingshot.slingshot :refer :all]
            [clj-http.client :as client]
            [pantomime.mime :refer [extension-for-name mime-type-of]]
            [buddy.core.codecs :refer [base64->bytes base64->str]]))

(def config (-> (clojure.java.io/resource "config/core.edn") slurp read-string))

