0
Fork 0
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:
Andrés Moya 2020-06-24 13:11:42 +02:00 committed by Andrey Antukh
parent 85bae6cf26
commit 72c36660b9
4 changed files with 69 additions and 36 deletions

View file

@ -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}))))

View file

@ -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]

View file

@ -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))

View file

@ -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)))