diff --git a/backend/src/uxbox/images.clj b/backend/src/uxbox/images.clj index bb590aae9..3ae3fd03c 100644 --- a/backend/src/uxbox/images.clj +++ b/backend/src/uxbox/images.clj @@ -20,7 +20,8 @@ [uxbox.common.exceptions :as ex] [uxbox.common.spec :as us] [uxbox.media :as media] - [uxbox.util.storage :as ust]) + [uxbox.util.storage :as ust] + [uxbox.util.http :as http]) (:import java.io.ByteArrayInputStream java.io.InputStream @@ -186,3 +187,24 @@ (us/assert map? row) (us/assert (s/coll-of vector?) pairs) (reduce #(resolve-uri media/media-storage %1 (nth %2 0) (nth %2 1)) row pairs)) + +(defn download-image + [url] + (let [result (http/get! url {:as :byte-array}) + data (:body result) + content-type (get (:headers result) "content-type") + format (mtype->format content-type)] + (if (nil? format) + (ex/raise :type :validation + :code :image-type-not-allowed + :hint "Seems like the url points to an invalid image.") + (let [tempfile (fs/create-tempfile) + base-filename (first (fs/split-ext (fs/name tempfile))) + filename (str base-filename (format->extension format))] + (with-open [ostream (io/output-stream tempfile)] + (.write ostream data)) + {:filename filename + :size (count data) + :tempfile tempfile + :content-type content-type})))) + diff --git a/backend/src/uxbox/services/mutations/files.clj b/backend/src/uxbox/services/mutations/files.clj index 0f53acec7..d4c0ddbf8 100644 --- a/backend/src/uxbox/services/mutations/files.clj +++ b/backend/src/uxbox/services/mutations/files.clj @@ -35,6 +35,7 @@ (s/def ::name ::us/string) (s/def ::profile-id ::us/uuid) (s/def ::project-id ::us/uuid) +(s/def ::url ::us/url) ;; --- Mutation: Create Project File @@ -127,17 +128,29 @@ nil) -;; --- Mutation: Upload File Image +;; --- Mutations: Create File Image (Upload and create from url) (declare create-file-image) (s/def ::file-id ::us/uuid) (s/def ::content ::imgs/upload) +(s/def ::add-file-image-from-url + (s/keys :req-un [::profile-id ::file-id ::name ::url] + :opt-un [::id])) + (s/def ::upload-file-image (s/keys :req-un [::profile-id ::file-id ::name ::content] :opt-un [::id])) +(sm/defmutation ::add-file-image-from-url + [{:keys [profile-id file-id url] :as params}] + (db/with-atomic [conn db/pool] + (files/check-edition-permissions! conn profile-id file-id) + (let [content (images/download-image url) + params' (merge params {:content content})] + (create-file-image conn params')))) + (sm/defmutation ::upload-file-image [{:keys [profile-id file-id] :as params}] (db/with-atomic [conn db/pool] diff --git a/backend/src/uxbox/services/mutations/images.clj b/backend/src/uxbox/services/mutations/images.clj index 90463c9a4..f4f51587c 100644 --- a/backend/src/uxbox/services/mutations/images.clj +++ b/backend/src/uxbox/services/mutations/images.clj @@ -10,7 +10,6 @@ (ns uxbox.services.mutations.images (:require [clojure.spec.alpha :as s] - [clojure.java.io :as io] [datoteka.core :as fs] [uxbox.common.exceptions :as ex] [uxbox.common.spec :as us] @@ -23,8 +22,7 @@ [uxbox.services.queries.teams :as teams] [uxbox.tasks :as tasks] [uxbox.util.storage :as ust] - [uxbox.util.time :as dt] - [uxbox.util.http :as http])) + [uxbox.util.time :as dt])) (def thumbnail-options {:width 800 @@ -107,10 +105,8 @@ nil))) +;; --- Create Image (Upload and create from url) -;; --- Create Image (Upload) - -(declare download-image) (declare create-image) (declare persist-image-on-fs) (declare persist-image-thumbnail-on-fs) @@ -140,36 +136,16 @@ :opt-un [::id])) (sm/defmutation ::add-image-from-url - [{:keys [library-id profile-id url] :as params}] + [{:keys [profile-id library-id url] :as params}] (db/with-atomic [conn db/pool] (let [lib (select-library-for-update conn library-id)] (teams/check-edition-permissions! conn profile-id (:team-id lib)) - (let [content (download-image url) + (let [content (images/download-image url) params' (merge params {:content content})] (create-image conn params'))))) -(defn download-image - [url] - (let [result (http/get! url {:as :byte-array}) - data (:body result) - content-type (get (:headers result) "content-type") - format (images/mtype->format content-type)] - (if (nil? format) - (ex/raise :type :validation - :code :image-type-not-allowed - :hint "Seems like the url points to an invalid image.") - (let [tempfile (fs/create-tempfile) - base-filename (get (fs/split-ext (fs/name tempfile)) 0) - filename (str base-filename (images/format->extension format))] - (with-open [ostream (io/output-stream tempfile)] - (.write ostream data)) - {:filename filename - :size (count data) - :tempfile tempfile - :content-type content-type})))) - (sm/defmutation ::upload-image - [{:keys [library-id profile-id] :as params}] + [{:keys [profile-id library-id] :as params}] (db/with-atomic [conn db/pool] (let [lib (select-library-for-update conn library-id)] (teams/check-edition-permissions! conn profile-id (:team-id lib)) diff --git a/backend/tests/uxbox/tests/test_services_files.clj b/backend/tests/uxbox/tests/test_services_files.clj index 7cea2f01e..90636ac47 100644 --- a/backend/tests/uxbox/tests/test_services_files.clj +++ b/backend/tests/uxbox/tests/test_services_files.clj @@ -135,6 +135,30 @@ proj-id (:default-project-id prof) file (th/create-file db/pool (:id prof) proj-id 1)] + (t/testing "create file image from url" + (let [url "https://raw.githubusercontent.com/uxbox/uxbox/develop/frontend/resources/images/penpot-login.jpg" + data {::sm/type :add-file-image-from-url + :profile-id (:id prof) + :file-id (:id file) + :name "testfile" + :url url} + out (th/try-on! (sm/handle data))] + + ;; (th/print-result! out) + (t/is (nil? (:error out))) + + (let [result (:result out)] + (t/is (= (:id file) (:file-id result))) + (t/is (= (:name data) (:name result))) + (t/is (= 787 (:width result))) + (t/is (= 2000 (:height result))) + (t/is (= "image/jpeg" (:mtype result))) + + (t/is (string? (:path result))) + (t/is (string? (:uri result))) + (t/is (string? (:thumb-path result))) + (t/is (string? (:thumb-uri result)))))) + (t/testing "upload file image" (let [content {:filename "sample.jpg" :tempfile (th/tempfile "uxbox/tests/_files/sample.jpg") @@ -144,9 +168,7 @@ :profile-id (:id prof) :file-id (:id file) :name "testfile" - :content content - :width 800 - :height 800} + :content content} out (th/try-on! (sm/handle data))] @@ -156,8 +178,8 @@ (let [result (:result out)] (t/is (= (:id file) (:file-id result))) (t/is (= (:name data) (:name result))) - (t/is (= (:width data) (:width result))) - (t/is (= (:height data) (:height result))) + (t/is (= 800 (:width result))) + (t/is (= 800 (:height result))) (t/is (= (:content-type content) (:mtype result))) (t/is (string? (:path result)))