0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 08:20:45 -05:00

🎉 Create add-image-from-url service

This commit is contained in:
Andrés Moya 2020-06-24 11:37:07 +02:00 committed by Andrey Antukh
parent c0cbb5877b
commit 85bae6cf26
4 changed files with 86 additions and 18 deletions

View file

@ -10,6 +10,7 @@
(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]
@ -22,7 +23,8 @@
[uxbox.services.queries.teams :as teams]
[uxbox.tasks :as tasks]
[uxbox.util.storage :as ust]
[uxbox.util.time :as dt]))
[uxbox.util.time :as dt]
[uxbox.util.http :as http]))
(def thumbnail-options
{:width 800
@ -35,7 +37,7 @@
(s/def ::profile-id ::us/uuid)
(s/def ::library-id ::us/uuid)
(s/def ::team-id ::us/uuid)
(s/def ::url ::us/url)
;; --- Create Library
@ -108,6 +110,7 @@
;; --- Create Image (Upload)
(declare download-image)
(declare create-image)
(declare persist-image-on-fs)
(declare persist-image-thumbnail-on-fs)
@ -128,10 +131,43 @@
(s/def ::content ::upload)
(s/def ::upload-image
(s/keys :req-un [::profile-id ::name ::content ::library-id]
(s/def ::add-image-from-url
(s/keys :req-un [::profile-id ::library-id ::name ::url]
:opt-un [::id]))
(s/def ::upload-image
(s/keys :req-un [::profile-id ::library-id ::name ::content]
:opt-un [::id]))
(sm/defmutation ::add-image-from-url
[{:keys [library-id profile-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)
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}]
(db/with-atomic [conn db/pool]

View file

@ -14,6 +14,11 @@
(def default-client
(delay (http/build-client {:executor @px/default-executor})))
(defn get!
[url opts]
(let [opts' (merge {:client @default-client :as :string} opts)]
(http/get url nil opts')))
(defn send!
[req]
(http/send req {:client @default-client :as :string}))

View file

@ -104,10 +104,36 @@
))
(t/deftest images-crud
(let [prof (th/create-profile db/pool 1)
team-id (:default-team-id prof)
lib (th/create-image-library db/pool team-id 1)
image-id (uuid/next)]
(let [prof (th/create-profile db/pool 1)
team-id (:default-team-id prof)
image-id-1 (uuid/next)
image-id-2 (uuid/next)
lib (th/create-image-library db/pool team-id 1)]
(t/testing "create image from url to library"
(let [url "https://raw.githubusercontent.com/uxbox/uxbox/develop/frontend/resources/images/penpot-login.jpg"
data {::sm/type :add-image-from-url
:id image-id-1
:profile-id (:id prof)
:library-id (:id lib)
:name "testfile"
:url url}
out (th/try-on! (sm/handle data))]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(t/is (= image-id-1 (get-in out [:result :id])))
(t/is (= "testfile" (get-in out [:result :name])))
(t/is (= "image/jpeg" (get-in out [:result :mtype])))
(t/is (= "image/jpeg" (get-in out [:result :thumb-mtype])))
(t/is (= 787 (get-in out [:result :width])))
(t/is (= 2000 (get-in out [:result :height])))
(t/is (string? (get-in out [:result :path])))
(t/is (string? (get-in out [:result :thumb-path])))
(t/is (string? (get-in out [:result :uri])))
(t/is (string? (get-in out [:result :thumb-uri])))))
(t/testing "upload image to library"
(let [content {:filename "sample.jpg"
@ -115,7 +141,7 @@
:content-type "image/jpeg"
:size 312043}
data {::sm/type :upload-image
:id image-id
:id image-id-2
:profile-id (:id prof)
:library-id (:id lib)
:name "testfile"
@ -125,7 +151,7 @@
;; (th/print-result! out)
(t/is (nil? (:error out)))
(t/is (= image-id (get-in out [:result :id])))
(t/is (= image-id-2 (get-in out [:result :id])))
(t/is (= "testfile" (get-in out [:result :name])))
(t/is (= "image/jpeg" (get-in out [:result :mtype])))
(t/is (= "image/jpeg" (get-in out [:result :thumb-mtype])))
@ -135,8 +161,7 @@
(t/is (string? (get-in out [:result :path])))
(t/is (string? (get-in out [:result :thumb-path])))
(t/is (string? (get-in out [:result :uri])))
(t/is (string? (get-in out [:result :thumb-uri])))
))
(t/is (string? (get-in out [:result :thumb-uri])))))
(t/testing "list images by library"
(let [data {::sq/type :images
@ -145,7 +170,8 @@
out (th/try-on! (sq/handle data))]
;; (th/print-result! out)
(t/is (= image-id (get-in out [:result 0 :id])))
;; Result is ordered by creation date descendent
(t/is (= image-id-2 (get-in out [:result 0 :id])))
(t/is (= "testfile" (get-in out [:result 0 :name])))
(t/is (= "image/jpeg" (get-in out [:result 0 :mtype])))
(t/is (= "image/jpeg" (get-in out [:result 0 :thumb-mtype])))
@ -160,11 +186,11 @@
(t/testing "single image"
(let [data {::sq/type :image
:profile-id (:id prof)
:id image-id}
:id image-id-2}
out (th/try-on! (sq/handle data))]
;; (th/print-result! out)
(t/is (= image-id (get-in out [:result :id])))
(t/is (= image-id-2 (get-in out [:result :id])))
(t/is (= "testfile" (get-in out [:result :name])))
(t/is (= "image/jpeg" (get-in out [:result :mtype])))
(t/is (= "image/jpeg" (get-in out [:result :thumb-mtype])))
@ -179,7 +205,7 @@
(t/testing "delete images"
(let [data {::sm/type :delete-image
:profile-id (:id prof)
:id image-id}
:id image-id-1}
out (th/try-on! (sm/handle data))]
;; (th/print-result! out)
@ -189,7 +215,7 @@
(t/testing "query image after delete"
(let [data {::sq/type :image
:profile-id (:id prof)
:id image-id}
:id image-id-1}
out (th/try-on! (sq/handle data))]
;; (th/print-result! out)
@ -208,5 +234,5 @@
out (th/try-on! (sq/handle data))]
;; (th/print-result! out)
(let [result (:result out)]
(t/is (= 0 (count result))))))
(t/is (= 1 (count result))))))
))

View file

@ -105,6 +105,7 @@
(s/def ::number (s/conformer number-conformer str))
(s/def ::integer (s/conformer integer-conformer str))
(s/def ::not-empty-string (s/and string? #(not (str/empty? %))))
(s/def ::url string?)
#?(:clj (s/def ::path (s/conformer path-conformer str)))
;; --- Macros