From 784a4f8ecd5ed147e236564ecaf683df279a4d6e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 15 Feb 2021 21:03:24 +0100 Subject: [PATCH] :sparkles: Add some type hints and remove legacy code. --- backend/src/app/db.clj | 7 +- backend/src/app/media.clj | 6 +- backend/src/app/notifications.clj | 6 +- backend/src/app/rpc/queries/files.clj | 5 +- backend/src/app/rpc/queries/recent_files.clj | 2 - backend/src/app/storage.clj | 2 +- backend/src/app/storage/impl.clj | 2 +- backend/src/app/util/blob.clj | 4 +- backend/src/app/util/emails.clj | 2 +- backend/src/app/util/svg.clj | 101 ------------------- backend/tests/app/tests/test_util_svg.clj | 62 ------------ 11 files changed, 18 insertions(+), 181 deletions(-) delete mode 100644 backend/src/app/util/svg.clj delete mode 100644 backend/tests/app/tests/test_util_svg.clj diff --git a/backend/src/app/db.clj b/backend/src/app/db.clj index 99e4da7d2..d85ece5bc 100644 --- a/backend/src/app/db.clj +++ b/backend/src/app/db.clj @@ -27,6 +27,7 @@ com.zaxxer.hikari.HikariConfig com.zaxxer.hikari.HikariDataSource com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory + java.lang.AutoCloseable java.sql.Connection java.sql.Savepoint org.postgresql.PGConnection @@ -59,7 +60,7 @@ (log/debugf "initialize connection pool %s with uri %s" (:name cfg) (:uri cfg)) (let [pool (create-pool cfg)] (when (seq migrations) - (with-open [conn (open pool)] + (with-open [conn ^AutoCloseable (open pool)] (mg/setup! conn) (doseq [[mname steps] migrations] (mg/migrate! conn {:name (name mname) :steps steps})))) @@ -164,7 +165,7 @@ [& args] `(jdbc/with-transaction ~@args)) -(defn open +(defn ^Connection open [pool] (jdbc/get-connection pool)) @@ -288,7 +289,7 @@ (pginterval data) (dt/duration? data) - (->> (/ (.toMillis data) 1000.0) + (->> (/ (.toMillis ^java.time.Duration data) 1000.0) (format "%s seconds") (pginterval)) diff --git a/backend/src/app/media.clj b/backend/src/app/media.clj index 14a4191e0..13219f23a 100644 --- a/backend/src/app/media.clj +++ b/backend/src/app/media.clj @@ -77,7 +77,7 @@ (assoc params :format format :mtype (cm/format->mtype format) - :size (alength thumbnail-data) + :size (alength ^bytes thumbnail-data) :data (ByteArrayInputStream. thumbnail-data))))) (defmulti process :cmd) @@ -89,7 +89,7 @@ (.addImage) (.autoOrient) (.strip) - (.thumbnail (int width) (int height) ">") + (.thumbnail ^Integer (int width) ^Integer (int height) ">") (.quality (double quality)) (.addImage))] (generic-process (assoc params :operation op)))) @@ -101,7 +101,7 @@ (.addImage) (.autoOrient) (.strip) - (.thumbnail (int width) (int height) "^") + (.thumbnail ^Integer (int width) ^Integer (int height) "^") (.gravity "center") (.extent (int width) (int height)) (.quality (double quality)) diff --git a/backend/src/app/notifications.clj b/backend/src/app/notifications.clj index 7aefa4e45..4ff66aac8 100644 --- a/backend/src/app/notifications.clj +++ b/backend/src/app/notifications.clj @@ -22,7 +22,9 @@ [ring.adapter.jetty9 :as jetty] [ring.middleware.cookies :refer [wrap-cookies]] [ring.middleware.keyword-params :refer [wrap-keyword-params]] - [ring.middleware.params :refer [wrap-params]])) + [ring.middleware.params :refer [wrap-params]]) + (:import + org.eclipse.jetty.websocket.api.WebSocketAdapter)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Http Handler @@ -187,7 +189,7 @@ (aa/ row changes (assoc :changes (blob/decode changes)) - data (assoc :data (blob/decode data)) - pages (assoc :pages (vec (.getArray pages)))))) + data (assoc :data (blob/decode data))))) (def decode-row-xf (comp (map decode-row) diff --git a/backend/src/app/rpc/queries/recent_files.clj b/backend/src/app/rpc/queries/recent_files.clj index 24a5653ea..1791b784b 100644 --- a/backend/src/app/rpc/queries/recent_files.clj +++ b/backend/src/app/rpc/queries/recent_files.clj @@ -41,5 +41,3 @@ (teams/check-read-permissions! conn profile-id team-id) (let [files (db/exec! conn [sql:recent-files team-id])] (into [] decode-row-xf files)))) - - diff --git a/backend/src/app/storage.clj b/backend/src/app/storage.clj index 7e5371d50..94e7e3b70 100644 --- a/backend/src/app/storage.clj +++ b/backend/src/app/storage.clj @@ -308,7 +308,7 @@ (if-let [[groups total] (retrieve-deleted-objects conn)] (do (run! (partial delete-in-bulk conn) groups) - (recur (+ n total))) + (recur (+ n ^long total))) (do (log/infof "gc-deleted: processed %s items" n) {:deleted n}))))))) diff --git a/backend/src/app/storage/impl.clj b/backend/src/app/storage/impl.clj index 450ae718c..00f356f56 100644 --- a/backend/src/app/storage/impl.clj +++ b/backend/src/app/storage/impl.clj @@ -165,7 +165,7 @@ (string->content data) (bytes? data) - (input-stream->content (ByteArrayInputStream. ^bytes data) (alength data)) + (input-stream->content (ByteArrayInputStream. ^bytes data) (alength ^bytes data)) (instance? InputStream data) (do diff --git a/backend/src/app/util/blob.clj b/backend/src/app/util/blob.clj index 332aedaeb..dd1624b1f 100644 --- a/backend/src/app/util/blob.clj +++ b/backend/src/app/util/blob.clj @@ -37,7 +37,7 @@ (defn encode ([data] (encode data nil)) ([data {:keys [version] :or {version default-version}}] - (case version + (case (long version) 1 (encode-v1 data) 2 (encode-v2 data) (throw (ex-info "unsupported version" {:version version}))))) @@ -81,7 +81,7 @@ (defn- encode-v2 [data] (let [data (n/fast-freeze data) - dlen (alength data) + dlen (alength ^bytes data) mlen (Zstd/compressBound dlen) cdata (byte-array mlen) clen (Zstd/compressByteArray ^bytes cdata 0 mlen diff --git a/backend/src/app/util/emails.clj b/backend/src/app/util/emails.clj index 813cf4367..a2111d6f8 100644 --- a/backend/src/app/util/emails.clj +++ b/backend/src/app/util/emails.clj @@ -161,7 +161,7 @@ (.setDebug session debug) session)) -(defn smtp-message +(defn ^MimeMessage smtp-message [cfg message] (let [^Session session (smtp-session cfg)] (build-message cfg session message))) diff --git a/backend/src/app/util/svg.clj b/backend/src/app/util/svg.clj deleted file mode 100644 index 04d404a81..000000000 --- a/backend/src/app/util/svg.clj +++ /dev/null @@ -1,101 +0,0 @@ -;; This Source Code Form is subject to the terms of the Mozilla Public -;; License, v. 2.0. If a copy of the MPL was not distributed with this -;; file, You can obtain one at http://mozilla.org/MPL/2.0/. -;; -;; This Source Code Form is "Incompatible With Secondary Licenses", as -;; defined by the Mozilla Public License, v. 2.0. -;; -;; Copyright (c) 2020 UXBOX Labs SL - -(ns app.util.svg - "Icons SVG parsing helpers." - (:require - [app.common.exceptions :as ex] - [app.common.spec :as us] - [clojure.spec.alpha :as s] - [cuerdas.core :as str]) - (:import - org.jsoup.Jsoup - org.jsoup.nodes.Attribute - org.jsoup.nodes.Element - org.jsoup.nodes.Document)) - -(s/def ::content string?) -(s/def ::width ::us/number) -(s/def ::height ::us/number) -(s/def ::name string?) -(s/def ::view-box (s/coll-of ::us/number :min-count 4 :max-count 4)) - -(s/def ::svg-entity - (s/keys :req-un [::content ::width ::height ::view-box] - :opt-un [::name])) - -;; --- Implementation - -(defn- parse-double - [data] - (s/assert ::us/string data) - (Double/parseDouble data)) - -(defn- parse-viewbox - [data] - (s/assert ::us/string data) - (mapv parse-double (str/split data #"\s+"))) - -(defn- parse-attrs - [^Element element] - (persistent! - (reduce (fn [acc ^Attribute attr] - (let [key (.getKey attr) - val (.getValue attr)] - (case key - "width" (assoc! acc :width (parse-double val)) - "height" (assoc! acc :height (parse-double val)) - "viewbox" (assoc! acc :view-box (parse-viewbox val)) - "sodipodi:docname" (assoc! acc :name val) - acc))) - (transient {}) - (.attributes element)))) - -(defn- impl-parse - [data] - (try - (let [document (Jsoup/parse ^String data) - element (some-> (.body ^Document document) - (.getElementsByTag "svg") - (first)) - content (.html element) - attrs (parse-attrs element)] - (assoc attrs :content content)) - (catch java.lang.IllegalArgumentException _e - (ex/raise :type :validation - :code ::invalid-input - :message "Input does not seems to be a valid svg.")) - (catch java.lang.NullPointerException _e - (ex/raise :type :validation - :code ::invalid-input - :message "Input does not seems to be a valid svg.")) - (catch org.jsoup.UncheckedIOException _e - (ex/raise :type :validation - :code ::invalid-input - :message "Input does not seems to be a valid svg.")) - (catch Exception _e - (ex/raise :type :internal - :code ::unexpected)))) - -;; --- Public Api - -(defn parse-string - "Parse SVG from a string." - [data] - (s/assert ::us/string data) - (let [result (impl-parse data)] - (if (s/valid? ::svg-entity result) - result - (ex/raise :type :validation - :code ::invalid-result - :message "The result does not conform valid svg entity.")))) - -(defn parse - [data] - (parse-string (slurp data))) diff --git a/backend/tests/app/tests/test_util_svg.clj b/backend/tests/app/tests/test_util_svg.clj deleted file mode 100644 index 929b8c867..000000000 --- a/backend/tests/app/tests/test_util_svg.clj +++ /dev/null @@ -1,62 +0,0 @@ -;; This Source Code Form is subject to the terms of the Mozilla Public -;; License, v. 2.0. If a copy of the MPL was not distributed with this -;; file, You can obtain one at http://mozilla.org/MPL/2.0/. -;; -;; This Source Code Form is "Incompatible With Secondary Licenses", as -;; defined by the Mozilla Public License, v. 2.0. -;; -;; Copyright (c) 2020 UXBOX Labs SL - -(ns app.tests.test-util-svg - (:require - [clojure.test :as t] - [clojure.java.io :as io] - [app.http :as http] - [app.util.svg :as svg] - [app.tests.helpers :as th])) - -(t/deftest parse-svg-1 - (let [result (-> (io/resource "app/tests/_files/sample1.svg") - (svg/parse))] - (t/is (contains? result :width)) - (t/is (contains? result :height)) - (t/is (contains? result :view-box)) - (t/is (contains? result :name)) - (t/is (contains? result :content)) - (t/is (= 500.0 (:width result))) - (t/is (= 500.0 (:height result))) - (t/is (= [0.0 0.0 500.00001 500.00001] (:view-box result))) - (t/is (= "lock.svg" (:name result))))) - -(t/deftest parse-svg-2 - (let [result (-> (io/resource "app/tests/_files/sample2.svg") - (svg/parse))] - (t/is (contains? result :width)) - (t/is (contains? result :height)) - (t/is (contains? result :view-box)) - (t/is (contains? result :name)) - (t/is (contains? result :content)) - (t/is (= 500.0 (:width result))) - (t/is (= 500.0 (:height result))) - (t/is (= [0.0 0.0 500.0 500.00001] (:view-box result))) - (t/is (= "play.svg" (:name result))))) - -(t/deftest parse-invalid-svg-1 - (let [image (io/resource "app/tests/_files/sample.jpg") - out (th/try! (svg/parse image))] - - (let [error (:error out)] - (t/is (th/ex-info? error)) - (t/is (th/ex-of-code? error ::svg/invalid-input))))) - -(t/deftest parse-invalid-svg-2 - (let [out (th/try! (svg/parse-string ""))] - (let [error (:error out)] - (t/is (th/ex-info? error)) - (t/is (th/ex-of-code? error ::svg/invalid-input))))) - -(t/deftest parse-invalid-svg-3 - (let [out (th/try! (svg/parse-string ""))] - (let [error (:error out)] - (t/is (th/ex-info? error)) - (t/is (th/ex-of-code? error ::svg/invalid-result)))))