mirror of
https://github.com/penpot/penpot.git
synced 2025-01-09 08:20:45 -05:00
🎉 Create add-file-image-from-url service
This commit is contained in:
parent
85bae6cf26
commit
72c36660b9
4 changed files with 69 additions and 36 deletions
|
@ -20,7 +20,8 @@
|
||||||
[uxbox.common.exceptions :as ex]
|
[uxbox.common.exceptions :as ex]
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.media :as media]
|
[uxbox.media :as media]
|
||||||
[uxbox.util.storage :as ust])
|
[uxbox.util.storage :as ust]
|
||||||
|
[uxbox.util.http :as http])
|
||||||
(:import
|
(:import
|
||||||
java.io.ByteArrayInputStream
|
java.io.ByteArrayInputStream
|
||||||
java.io.InputStream
|
java.io.InputStream
|
||||||
|
@ -186,3 +187,24 @@
|
||||||
(us/assert map? row)
|
(us/assert map? row)
|
||||||
(us/assert (s/coll-of vector?) pairs)
|
(us/assert (s/coll-of vector?) pairs)
|
||||||
(reduce #(resolve-uri media/media-storage %1 (nth %2 0) (nth %2 1)) row 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}))))
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
(s/def ::name ::us/string)
|
(s/def ::name ::us/string)
|
||||||
(s/def ::profile-id ::us/uuid)
|
(s/def ::profile-id ::us/uuid)
|
||||||
(s/def ::project-id ::us/uuid)
|
(s/def ::project-id ::us/uuid)
|
||||||
|
(s/def ::url ::us/url)
|
||||||
|
|
||||||
;; --- Mutation: Create Project File
|
;; --- Mutation: Create Project File
|
||||||
|
|
||||||
|
@ -127,17 +128,29 @@
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
|
||||||
;; --- Mutation: Upload File Image
|
;; --- Mutations: Create File Image (Upload and create from url)
|
||||||
|
|
||||||
(declare create-file-image)
|
(declare create-file-image)
|
||||||
|
|
||||||
(s/def ::file-id ::us/uuid)
|
(s/def ::file-id ::us/uuid)
|
||||||
(s/def ::content ::imgs/upload)
|
(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/def ::upload-file-image
|
||||||
(s/keys :req-un [::profile-id ::file-id ::name ::content]
|
(s/keys :req-un [::profile-id ::file-id ::name ::content]
|
||||||
:opt-un [::id]))
|
: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
|
(sm/defmutation ::upload-file-image
|
||||||
[{:keys [profile-id file-id] :as params}]
|
[{:keys [profile-id file-id] :as params}]
|
||||||
(db/with-atomic [conn db/pool]
|
(db/with-atomic [conn db/pool]
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
(ns uxbox.services.mutations.images
|
(ns uxbox.services.mutations.images
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[clojure.java.io :as io]
|
|
||||||
[datoteka.core :as fs]
|
[datoteka.core :as fs]
|
||||||
[uxbox.common.exceptions :as ex]
|
[uxbox.common.exceptions :as ex]
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
|
@ -23,8 +22,7 @@
|
||||||
[uxbox.services.queries.teams :as teams]
|
[uxbox.services.queries.teams :as teams]
|
||||||
[uxbox.tasks :as tasks]
|
[uxbox.tasks :as tasks]
|
||||||
[uxbox.util.storage :as ust]
|
[uxbox.util.storage :as ust]
|
||||||
[uxbox.util.time :as dt]
|
[uxbox.util.time :as dt]))
|
||||||
[uxbox.util.http :as http]))
|
|
||||||
|
|
||||||
(def thumbnail-options
|
(def thumbnail-options
|
||||||
{:width 800
|
{:width 800
|
||||||
|
@ -107,10 +105,8 @@
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
|
|
||||||
|
;; --- Create Image (Upload and create from url)
|
||||||
|
|
||||||
;; --- Create Image (Upload)
|
|
||||||
|
|
||||||
(declare download-image)
|
|
||||||
(declare create-image)
|
(declare create-image)
|
||||||
(declare persist-image-on-fs)
|
(declare persist-image-on-fs)
|
||||||
(declare persist-image-thumbnail-on-fs)
|
(declare persist-image-thumbnail-on-fs)
|
||||||
|
@ -140,36 +136,16 @@
|
||||||
:opt-un [::id]))
|
:opt-un [::id]))
|
||||||
|
|
||||||
(sm/defmutation ::add-image-from-url
|
(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]
|
(db/with-atomic [conn db/pool]
|
||||||
(let [lib (select-library-for-update conn library-id)]
|
(let [lib (select-library-for-update conn library-id)]
|
||||||
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
(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})]
|
params' (merge params {:content content})]
|
||||||
(create-image conn params')))))
|
(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
|
(sm/defmutation ::upload-image
|
||||||
[{:keys [library-id profile-id] :as params}]
|
[{:keys [profile-id library-id] :as params}]
|
||||||
(db/with-atomic [conn db/pool]
|
(db/with-atomic [conn db/pool]
|
||||||
(let [lib (select-library-for-update conn library-id)]
|
(let [lib (select-library-for-update conn library-id)]
|
||||||
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
(teams/check-edition-permissions! conn profile-id (:team-id lib))
|
||||||
|
|
|
@ -135,6 +135,30 @@
|
||||||
proj-id (:default-project-id prof)
|
proj-id (:default-project-id prof)
|
||||||
file (th/create-file db/pool (:id prof) proj-id 1)]
|
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"
|
(t/testing "upload file image"
|
||||||
(let [content {:filename "sample.jpg"
|
(let [content {:filename "sample.jpg"
|
||||||
:tempfile (th/tempfile "uxbox/tests/_files/sample.jpg")
|
:tempfile (th/tempfile "uxbox/tests/_files/sample.jpg")
|
||||||
|
@ -144,9 +168,7 @@
|
||||||
:profile-id (:id prof)
|
:profile-id (:id prof)
|
||||||
:file-id (:id file)
|
:file-id (:id file)
|
||||||
:name "testfile"
|
:name "testfile"
|
||||||
:content content
|
:content content}
|
||||||
:width 800
|
|
||||||
:height 800}
|
|
||||||
|
|
||||||
out (th/try-on! (sm/handle data))]
|
out (th/try-on! (sm/handle data))]
|
||||||
|
|
||||||
|
@ -156,8 +178,8 @@
|
||||||
(let [result (:result out)]
|
(let [result (:result out)]
|
||||||
(t/is (= (:id file) (:file-id result)))
|
(t/is (= (:id file) (:file-id result)))
|
||||||
(t/is (= (:name data) (:name result)))
|
(t/is (= (:name data) (:name result)))
|
||||||
(t/is (= (:width data) (:width result)))
|
(t/is (= 800 (:width result)))
|
||||||
(t/is (= (:height data) (:height result)))
|
(t/is (= 800 (:height result)))
|
||||||
(t/is (= (:content-type content) (:mtype result)))
|
(t/is (= (:content-type content) (:mtype result)))
|
||||||
|
|
||||||
(t/is (string? (:path result)))
|
(t/is (string? (:path result)))
|
||||||
|
|
Loading…
Reference in a new issue