♻️ Refactor exporter

- Migrate from puppeteer to playwright
- Fix many lifecycle and resource usage issues
- Add redis integration
- Enable multiple exportation
- Enable asynchronos exportation (with progress reporting)
This commit is contained in:
Andrey Antukh 2022-03-18 12:34:02 +01:00 committed by Alonso Torres
parent f0a9889f33
commit 4a9e38a221
21 changed files with 1366 additions and 1017 deletions

View file

@ -13,46 +13,33 @@
[app.common.spec :as us]
[app.config :as cf]
[cljs.spec.alpha :as s]
[lambdaisland.uri :as u]
[promesa.core :as p]))
(defn create-cookie
[uri token]
(let [domain (str (:host uri)
(when (:port uri)
(str ":" (:port uri))))]
{:domain domain
:key "auth-token"
:value token}))
(defn pdf-from-object
[{:keys [file-id page-id object-id token scale type save-path]}]
(letfn [(handle [page]
(let [path (str "/render-object/" file-id "/" page-id "/" object-id)
uri (-> (u/uri (cf/get :public-uri))
(assoc :path "/")
(assoc :query "essential=t")
(assoc :fragment path))
cookie (create-cookie uri token)]
(pdf-from page (str uri) cookie)))
(pdf-from [page uri cookie]
(l/info :uri uri)
(p/let [options {:cookie cookie}]
(bw/configure-page! page options)
(bw/navigate! page uri)
(bw/wait-for page "#screenshot")
;; taking png screenshot before pdf, helps to make the
;; pdf rendering works as expected.
(p/let [dom (bw/select page "#screenshot")]
(bw/screenshot dom {:full-page? true}))
(if save-path
(bw/pdf page {:save-path save-path})
(bw/pdf page))))]
(bw/exec! handle)))
[{:keys [file-id page-id object-id token scale type save-path uri] :as params}]
(p/let [path (str "/render-object/" file-id "/" page-id "/" object-id)
uri (-> (or uri (cf/get :public-uri))
(assoc :path "/")
(assoc :fragment path))]
(bw/exec!
#js {:screen #js {:width bw/default-viewport-width
:height bw/default-viewport-height}
:viewport #js {:width bw/default-viewport-width
:height bw/default-viewport-height}
:locale "en-US"
:storageState #js {:cookies (bw/create-cookies uri {:token token})}
:deviceScaleFactor scale
:userAgent bw/default-user-agent}
(fn [page]
(l/info :uri uri)
(p/do!
(bw/nav! page uri)
(p/let [dom (bw/select page "#screenshot")]
(bw/wait-for dom)
(bw/screenshot dom {:full-page? true})
(if save-path
(bw/pdf page {:save-path save-path})
(bw/pdf page))))))))
(s/def ::name ::us/string)
(s/def ::suffix ::us/string)
@ -61,22 +48,21 @@
(s/def ::object-id ::us/uuid)
(s/def ::scale ::us/number)
(s/def ::token ::us/string)
(s/def ::filename ::us/string)
(s/def ::save-path ::us/string)
(s/def ::uri ::us/uri)
(s/def ::render-params
(s/keys :req-un [::name ::suffix ::object-id ::page-id ::scale ::token ::file-id]
:opt-un [::filename ::save-path]))
:opt-un [::save-path ::uri]))
(defn render
[params]
(us/assert ::render-params params)
(p/let [content (pdf-from-object params)]
{:content content
:filename (or (:filename params)
(str (:name params)
(:suffix params "")
".pdf"))
:length (alength content)
:mime-type "application/pdf"}))
{:data content
:name (str (:name params)
(:suffix params "")
".pdf")
:size (alength content)
:mtype "application/pdf"}))