diff --git a/backend/deps.edn b/backend/deps.edn index 54ecead9a..e0493c88d 100644 --- a/backend/deps.edn +++ b/backend/deps.edn @@ -5,7 +5,7 @@ funcool/cuerdas {:mvn/version "2.2.0"} funcool/datoteka {:git/url "https://github.com/funcool/datoteka.git" - :sha "b75f08fd59013577dd5e743d0b013dede6c6dc66"} + :sha "bae298a642b40e84e92dc195a68444bc63e807d9"} funcool/struct {:mvn/version "1.4.0"} diff --git a/backend/resources/sql/images.sql b/backend/resources/sql/images.sql index 23e3c0a01..2db2c9cac 100644 --- a/backend/resources/sql/images.sql +++ b/backend/resources/sql/images.sql @@ -63,4 +63,5 @@ returning *; -- :name delete-image :! :n update images set deleted_at = clock_timestamp() - where id = :id and "user" = :user; + where id = :id and "user" = :user +returning *; diff --git a/backend/src/user.clj b/backend/src/user.clj index 603000689..ed3d92fe7 100644 --- a/backend/src/user.clj +++ b/backend/src/user.clj @@ -27,7 +27,8 @@ (defn- start [] - (mount/start)) + (-> (mount/except #{#'uxbox.scheduled-jobs/scheduler}) + (mount/start))) (defn- stop [] diff --git a/backend/src/uxbox/images.clj b/backend/src/uxbox/images.clj index 3f1b2bf23..f145ff19e 100644 --- a/backend/src/uxbox/images.clj +++ b/backend/src/uxbox/images.clj @@ -6,18 +6,20 @@ (ns uxbox.images "Image postprocessing." - (:require [clojure.spec.alpha :as s] - [clojure.java.io :as io] - [datoteka.storages :as st] - [datoteka.core :as fs] - [datoteka.proto :as pt] - [uxbox.util.spec :as us] - [uxbox.media :as media] - [uxbox.util.data :refer (dissoc-in)]) - (:import java.io.InputStream - java.io.ByteArrayInputStream - org.im4java.core.IMOperation - org.im4java.core.ConvertCmd)) + (:require + [clojure.java.io :as io] + [clojure.spec.alpha :as s] + [datoteka.core :as fs] + [datoteka.proto :as pt] + [datoteka.storages :as st] + [uxbox.media :as media] + [uxbox.util.data :refer (dissoc-in)] + [uxbox.util.spec :as us]) + (:import + java.io.ByteArrayInputStream + java.io.InputStream + org.im4java.core.ConvertCmd + org.im4java.core.IMOperation)) ;; --- Thumbnails Generation @@ -59,13 +61,11 @@ {:pre [(us/valid? ::thumbnail-opts opts) (or (string? input) (fs/path input))]} - (let [parent (fs/parent input) - [filename ext] (fs/split-ext (fs/name input)) - + (let [[filename ext] (fs/split-ext (fs/name input)) suffix (->> [width height quality format] (interpose ".") (apply str)) - thumbnail-path (fs/path parent (str filename "-" suffix)) + thumbnail-path (fs/path input (str "thumb-" suffix)) images-storage media/images-storage thumbs-storage media/thumbnails-storage] (if @(st/exists? thumbs-storage thumbnail-path) diff --git a/backend/src/uxbox/media.clj b/backend/src/uxbox/media.clj index a3b9e904d..64a365b76 100644 --- a/backend/src/uxbox/media.clj +++ b/backend/src/uxbox/media.clj @@ -9,11 +9,40 @@ (:require [mount.core :refer [defstate]] [clojure.java.io :as io] [cuerdas.core :as str] + [datoteka.core :as fs] + [datoteka.proto :as stp] [datoteka.storages :as st] [datoteka.storages.local :refer [localfs]] [datoteka.storages.misc :refer [hashed scoped]] [uxbox.config :refer [config]])) +;; --- Backends + +(defn- normalize-filename + [path] + (let [parent (or (fs/parent path) "") + [name ext] (fs/split-ext (fs/name path))] + (fs/path parent (str (str/uslug name) ext)))) + +(defrecord FilenameSlugifiedBackend [storage] + stp/IPublicStorage + (-public-uri [_ path] + (stp/-public-uri storage path)) + + stp/IStorage + (-save [_ path content] + (let [^Path path (normalize-filename path)] + (stp/-save storage path content))) + + (-delete [_ path] + (stp/-delete storage path)) + + (-exists? [this path] + (stp/-exists? storage path)) + + (-lookup [_ path] + (stp/-lookup storage path))) + ;; --- State (defstate assets-storage @@ -29,10 +58,12 @@ (defstate images-storage :start (-> media-storage (scoped "images") - (hashed))) + (hashed) + (->FilenameSlugifiedBackend))) (defstate thumbnails-storage - :start (scoped media-storage "thumbs")) + :start (-> media-storage + (scoped "thumbs"))) ;; --- Public Api diff --git a/backend/src/uxbox/services/images.clj b/backend/src/uxbox/services/images.clj index d8c2de5dd..7f8438cbf 100644 --- a/backend/src/uxbox/services/images.clj +++ b/backend/src/uxbox/services/images.clj @@ -199,10 +199,18 @@ ;; --- Delete Image +(defn- delete-image-from-storage + [{:keys [path] :as image}] + (when @(st/exists? media/images-storage path) + @(st/delete media/images-storage path)) + (when @(st/exists? media/thumbnails-storage path) + @(st/delete media/thumbnails-storage path))) + (defn delete-image [conn {:keys [user id]}] (let [sqlv (sql/delete-image {:id id :user user})] - (pos? (sc/execute conn sqlv)))) + (some-> (sc/fetch-one conn sqlv) + (delete-image-from-storage)))) (s/def ::delete-image (s/keys :req-un [::user] @@ -212,7 +220,7 @@ [params] (s/assert ::delete-image params) (with-open [conn (db/connection)] - (delete-image conn params))) + (sc/apply-atomic conn delete-image params))) ;; --- List Images