<commit_before>;; 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/.
;;
;; Copyright (c) 2019 <NAME> <<EMAIL>>

(ns uxbox.services.mutations.images
  (:require
   [clojure.spec.alpha :as s]
   [datoteka.core :as fs]
   [datoteka.storages :as ds]
   [promesa.core :as p]
   [promesa.exec :as px]
   [uxbox.common.exceptions :as ex]
   [uxbox.common.spec :as us]
   [uxbox.db :as db]
   [uxbox.media :as media]
   [uxbox.images :as images]
   [uxbox.services.mutations :as sm]
   [uxbox.services.util :as su]
   [uxbox.util.blob :as blob]
   [uxbox.util.data :as data]
   [uxbox.util.uuid :as uuid]
   [vertx.core :as vc]))

(def +thumbnail-options+
  {:src :path
   :dst :thumbnail
   :width 300
   :height 100
   :quality 92
   :format "webp"})

(defn- populate-thumbnail
  [row]
  (let [opts +thumbnail-options+]
    (-> (px/submit! #(images/populate-thumbnails row opts))
        (su/handle-on-context))))

(defn- populate-thumbnails
  [rows]
  (if (empty? rows)
    rows
    (p/all (map populate-thumbnail rows))))

(defn- populate-urls
  [row]
  (images/populate-urls row media/images-storage :path :url))

(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::user ::us/uuid)
(s/def ::collection-id (s/nilable ::us/uuid))

;; --- Create Collection

(s/def ::create-image-collection
  (s/keys :req-un [::user ::us/name]
          :opt-un [::id]))

(sm/defmutation ::create-image-collection
  [{:keys [id user name] :as params}]
  (let [sql "insert into image_collections (id, user_id, name)
             values ($1, $2, $3) returning *;"]
    (db/query-one db/pool [sql (or id (uuid/next)) user name])))

;; --- Update Collection

(s/def ::update-images-collection
  (s/keys :req-un [::id ::user ::us/name]))

(sm/defmutation ::update-images-collection
  [{:keys [id user name] :as params}]
  (let [sql "update image_collections
                set name = $3
              where id = $1
                and user_id = $2
             returning *;"]
    (db/query-one db/pool [sql id user name])))

;; --- Delete Collection

(s/def ::delete-images-collection
  (s/keys :req-un [::user ::id]))

(sm/defmutation ::delete-images-collection
  [{:keys [id user] :as params}]
  (let [sql "update image_collections
                set deleted_at = clock_timestamp()
              where id = $1
                and user_id = $2
             returning id"]
    (-> (db/query-one db/pool [sql id user])
        (p/then' su/raise-not-found-if-nil))))

;; --- Create Image (Upload)

(defn- store-image-in-fs
  [{:keys [name path] :as upload}]
  (let [filename (fs/name name)
        storage media/images-storage]
    (-> (ds/save storage filename path)
        (su/handle-on-context))))

(def sql:create-image
  "insert into images (user_id, name, collection_id, path, width, height, mimetype)
   values ($1, $2, $3, $4, $5, $6, $7) returning *")

(defn- store-image-in-db
  [conn {:keys [id user name path collection-id height width mimetype]}]
  (let [sqlv [sql:create-image user name collection-id
              path width height mimetype]]
    (-> (db/query-one conn sqlv)
        (p/then populate-thumbnail)
        (p/then populate-urls))))<commit_msg>:bug: Fix bug on uploading image.<commit_after>;; 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/.
;;
;; Copyright (c) 2019 <NAME> <<EMAIL>>

(ns uxbox.services.mutations.images
  (:require
   [clojure.spec.alpha :as s]
   [datoteka.core :as fs]
   [datoteka.storages :as ds]
   [promesa.core :as p]
   [promesa.exec :as px]
   [uxbox.common.exceptions :as ex]
   [uxbox.common.spec :as us]
   [uxbox.db :as db]
   [uxbox.media :as media]
   [uxbox.images :as images]
   [uxbox.services.mutations :as sm]
   [uxbox.services.util :as su]
   [uxbox.util.blob :as blob]
   [uxbox.util.data :as data]
   [uxbox.util.uuid :as uuid]
   [vertx.core :as vc]))

(def +thumbnail-options+
  {:src :path
   :dst :thumbnail
   :width 300
   :height 100
   :quality 92
   :format "webp"})

(defn- populate-thumbnail
  [row]
  (let [opts +thumbnail-options+]
    (-> (px/submit! #(images/populate-thumbnails row opts))
        (su/handle-on-context))))

(defn- populate-thumbnails
  [rows]
  (if (empty? rows)
    rows
    (p/all (map populate-thumbnail rows))))

(defn- populate-urls
  [row]
  (images/populate-urls row media/images-storage :path :url))

(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::user ::us/uuid)
(s/def ::collection-id (s/nilable ::us/uuid))

;; --- Create Collection

(s/def ::create-image-collection
  (s/keys :req-un [::user ::us/name]
          :opt-un [::id]))

(sm/defmutation ::create-image-collection
  [{:keys [id user name] :as params}]
  (let [sql "insert into image_collections (id, user_id, name)
             values ($1, $2, $3) returning *;"]
    (db/query-one db/pool [sql (or id (uuid/next)) user name])))

;; --- Update Collection

(s/def ::update-images-collection
  (s/keys :req-un [::id ::user ::us/name]))

(sm/defmutation ::update-images-collection
  [{:keys [id user name] :as params}]
  (let [sql "update image_collections
                set name = $3
              where id = $1
                and user_id = $2
             returning *;"]
    (db/query-one db/pool [sql id user name])))

;; --- Delete Collection

(s/def ::delete-images-collection
  (s/keys :req-un [::user ::id]))

(sm/defmutation ::delete-images-collection
  [{:keys [id user] :as params}]
  (let [sql "update image_collections
                set deleted_at = clock_timestamp()
              where id = $1
                and user_id = $2
             returning id"]
    (-> (db/query-one db/pool [sql id user])
        (p/then' su/raise-not-found-if-nil))))

;; --- Create Image (Upload)

(defn- store-image-in-fs
  [{:keys [name path] :as upload}]
  (let [filename (fs/name name)
        storage media/images-storage]
    (-> (ds/save storage filename (fs/path path))
        (su/handle-on-context))))

(def sql:create-image
  "insert into images (user_id, name, collection_id, path, width, height, mimetype)
   values ($1, $2, $3, $4, $5, $6, $7) returning *")

(defn- store-image-in-db
  [conn {:keys [id user name path collection-id height width mimetype]}]
  (let [sqlv [sql:create-image user name collection-id
              path width height mimetype]]
    (-> (db/query-one conn sqlv)
        (p/then populate-thumbnail)
        (p/then populate-urls))))
{'fraction_non_alphanumeric': 0.16676718938480095, 'fraction_numerical': 0.009348612786489748, 'mean_word_length': 2.7837992013690815, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3862741', 'n_tokens_mistral': 2436, 'n_tokens_neox': 2384, 'n_words': 669}