mirror of
https://github.com/penpot/penpot.git
synced 2025-02-23 07:16:07 -05:00
feat(backend): remove catacumba dependency
This commit is contained in:
parent
910e076e73
commit
f64bb74a3e
24 changed files with 91 additions and 1233 deletions
|
@ -5,7 +5,6 @@
|
|||
funcool/promesa {:mvn/version "2.0.0"}
|
||||
funcool/cuerdas {:mvn/version "2.2.0"}
|
||||
funcool/datoteka {:mvn/version "1.0.0"}
|
||||
funcool/catacumba {:mvn/version "2.1.0"}
|
||||
funcool/struct {:mvn/version "1.4.0"}
|
||||
|
||||
ring/ring {:mvn/version "1.7.1"}
|
||||
|
@ -15,6 +14,7 @@
|
|||
metosin/reitit-spec {:mvn/version "0.3.7"}
|
||||
metosin/reitit-dev {:mvn/version "0.3.7"}
|
||||
|
||||
danlentz/clj-uuid {:mvn/version "0.1.9"}
|
||||
org.jsoup/jsoup {:mvn/version "1.10.2"}
|
||||
hiccup/hiccup {:mvn/version "1.0.5"}
|
||||
org.im4java/im4java {:mvn/version "1.4.0"}
|
||||
|
|
67
backend/src/uxbox/api/debug_emails.clj
Normal file
67
backend/src/uxbox/api/debug_emails.clj
Normal file
|
@ -0,0 +1,67 @@
|
|||
;; 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 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.api.debug-emails
|
||||
"A helper namespace for just render emails."
|
||||
(:require [clojure.edn :as edn]
|
||||
[hiccup.page :refer (html5)]
|
||||
[uxbox.emails :as emails]
|
||||
[uxbox.emails.core :as emails-core]))
|
||||
|
||||
;; (def +available-emails+
|
||||
;; {:users/register
|
||||
;; {:name "Cirilla"}
|
||||
;; :users/password-recovery
|
||||
;; {:name "Cirilla"
|
||||
;; :token "agNFhA6SolcFb4Us2NOTNWh0cfFDquVLAav400xQPjw"}})
|
||||
|
||||
;; (defn- render-emails-list
|
||||
;; []
|
||||
;; (html5
|
||||
;; [:section {:style "font-family: Monoid, monospace; font-size: 14px;"}
|
||||
;; [:h1 "Available emails"]
|
||||
;; [:table {:style "width: 500px;"}
|
||||
;; [:tbody
|
||||
;; [:tr
|
||||
;; (for [[type email] @emails-core/emails]
|
||||
;; [:tr
|
||||
;; [:td (pr-str type)]
|
||||
;; [:td
|
||||
;; [:a {:href (str "/debug/emails/email?id="
|
||||
;; (pr-str type)
|
||||
;; "&type=:text/html")}
|
||||
;; "(html)"]]
|
||||
;; [:td
|
||||
;; [:a {:href (str "/debug/emails/email?id="
|
||||
;; (pr-str type)
|
||||
;; "&type=:text/plain")}
|
||||
;; "(text)"]]])]]]]))
|
||||
|
||||
;; (defn list-emails
|
||||
;; [context]
|
||||
;; (http/ok (render-emails-list)
|
||||
;; {:content-type "text/html; charset=utf-8"}))
|
||||
|
||||
;; (defn- render-email
|
||||
;; [type content]
|
||||
;; (if (= type :text/html)
|
||||
;; content
|
||||
;; (html5
|
||||
;; [:pre content])))
|
||||
|
||||
;; (defn show-email
|
||||
;; [{params :query-params}]
|
||||
;; (let [id (edn/read-string (:id params))
|
||||
;; type (or (edn/read-string (:type params)) :text/html)
|
||||
;; params (-> (get +available-emails+ id)
|
||||
;; (assoc :email/name id))
|
||||
;; email (emails/render params)
|
||||
;; content (->> (:body email)
|
||||
;; (filter #(= (:uxbox.emails.core/type %) type))
|
||||
;; (first)
|
||||
;; (:content))]
|
||||
;; (-> (render-email type content)
|
||||
;; (http/ok {:content-type "text/html; charset=utf-8"}))))
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
(ns uxbox.api.middleware
|
||||
(:require [promesa.core :as p]
|
||||
[buddy.core.hash :as hash]
|
||||
[buddy.core.codecs :as codecs]
|
||||
[buddy.core.codecs.base64 :as b64]
|
||||
[reitit.core :as rc]
|
||||
[reitit.ring.middleware.multipart :as multipart]
|
||||
[reitit.ring.middleware.muuntaja :as muuntaja]
|
||||
|
@ -115,6 +118,18 @@
|
|||
;; "content-type"
|
||||
;; "authorization"])})
|
||||
|
||||
;; (defn digest
|
||||
;; [^bytes data]
|
||||
;; (-> (hash/blake2b-256 data)
|
||||
;; (b64/encode true)
|
||||
;; (codecs/bytes->str)))
|
||||
|
||||
;; (defn- etag-match?
|
||||
;; [^Request request ^String new-tag]
|
||||
;; (let [^Headers headers (.getHeaders request)]
|
||||
;; (when-let [etag (.get headers "if-none-match")]
|
||||
;; (= etag new-tag))))
|
||||
|
||||
(def ^:private exception-middleware
|
||||
(exception/create-exception-middleware
|
||||
(assoc exception/default-handlers
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"A initial fixtures."
|
||||
(:require [buddy.hashers :as hashers]
|
||||
[buddy.core.codecs :as codecs]
|
||||
[catacumba.serializers :as sz]
|
||||
[mount.core :as mount]
|
||||
[clj-uuid :as uuid]
|
||||
[suricatta.core :as sc]
|
||||
|
|
|
@ -1,163 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend
|
||||
(:require [mount.core :refer [defstate]]
|
||||
[catacumba.core :as ct]
|
||||
[catacumba.http :as http]
|
||||
[catacumba.serializers :as sz]
|
||||
[catacumba.handlers.auth :as cauth]
|
||||
[catacumba.handlers.parse :as cparse]
|
||||
[catacumba.handlers.misc :as cmisc]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.frontend.auth :as auth]
|
||||
[uxbox.frontend.users :as users]
|
||||
[uxbox.frontend.errors :as errors]
|
||||
[uxbox.frontend.projects :as projects]
|
||||
[uxbox.frontend.pages :as pages]
|
||||
[uxbox.frontend.images :as images]
|
||||
[uxbox.frontend.icons :as icons]
|
||||
[uxbox.frontend.kvstore :as kvstore]
|
||||
[uxbox.frontend.svgparse :as svgparse]
|
||||
[uxbox.frontend.debug-emails :as dbgemails]
|
||||
[uxbox.util.response :refer [rsp]]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Top Level Handlers
|
||||
|
||||
(defn- welcome-api
|
||||
"A GET entry point for the api that shows
|
||||
a welcome message."
|
||||
[context]
|
||||
(let [body {:message "Welcome to UXBox api."}]
|
||||
(-> (sz/encode body :json)
|
||||
(http/ok {:content-type "application/json"}))))
|
||||
|
||||
(defn- debug-only
|
||||
[context]
|
||||
(if (-> cfg/config :server :debug)
|
||||
(ct/delegate)
|
||||
(http/not-found "")))
|
||||
|
||||
;; --- Config
|
||||
|
||||
(def cors-conf
|
||||
{:origin "*"
|
||||
:max-age 3600
|
||||
:allow-methods #{:post :put :get :delete :trace}
|
||||
:allow-headers #{:x-requested-with :content-type :authorization}})
|
||||
|
||||
;; --- Routes
|
||||
|
||||
(def auth-opts
|
||||
{:alg :a256kw :enc :a128cbc-hs256})
|
||||
|
||||
(defn routes
|
||||
([] (routes cfg/config))
|
||||
([config]
|
||||
(let [auth-opts {:secret cfg/secret
|
||||
:options auth-opts}]
|
||||
(ct/routes
|
||||
[[:any (cauth/auth (cauth/jwe-backend auth-opts))]
|
||||
[:any (cmisc/autoreloader)]
|
||||
|
||||
[:get "api" #'welcome-api]
|
||||
|
||||
;; Serve assets on development server
|
||||
[:assets "media" {:dir "media"}]
|
||||
[:assets "static" {:dir "static"}]
|
||||
|
||||
[:prefix "debug"
|
||||
[:any debug-only]
|
||||
[:get "emails" #'dbgemails/list-emails]
|
||||
[:get "emails/email" #'dbgemails/show-email]]
|
||||
|
||||
[:prefix "api"
|
||||
[:any (cmisc/cors cors-conf)]
|
||||
[:any (cparse/body-params)]
|
||||
[:error #'errors/handler]
|
||||
|
||||
[:post "auth/token" #'auth/login]
|
||||
[:post "auth/register" #'users/register-user]
|
||||
[:get "auth/recovery/:token" #'users/validate-recovery-token]
|
||||
[:post "auth/recovery" #'users/request-recovery]
|
||||
[:put "auth/recovery" #'users/recover-password]
|
||||
|
||||
[:get "library/images/:id" #'images/retrieve-image]
|
||||
|
||||
[:get "projects-by-token/:token" #'projects/retrieve-project-by-share-token]
|
||||
|
||||
;; SVG Parse
|
||||
[:post "svg/parse" #'svgparse/parse]
|
||||
|
||||
[:any #'auth/authorization]
|
||||
|
||||
;; KVStore
|
||||
[:put "kvstore" #'kvstore/update]
|
||||
[:get "kvstore/:key" #'kvstore/retrieve]
|
||||
[:delete "kvstore/:key" #'kvstore/delete]
|
||||
|
||||
;; Projects
|
||||
[:get "projects/:id/pages" #'pages/list-pages-by-project]
|
||||
[:put "projects/:id" #'projects/update-project]
|
||||
[:delete "projects/:id" #'projects/delete-project]
|
||||
[:post "projects" #'projects/create-project]
|
||||
[:get "projects" #'projects/list-projects]
|
||||
|
||||
;; Image Collections
|
||||
[:put "library/image-collections/:id" #'images/update-collection]
|
||||
[:delete "library/image-collections/:id" #'images/delete-collection]
|
||||
[:get "library/image-collections" #'images/list-collections]
|
||||
[:post "library/image-collections" #'images/create-collection]
|
||||
[:get "library/image-collections/:id/images" #'images/list-images]
|
||||
[:get "library/image-collections/images" #'images/list-images]
|
||||
|
||||
;; Images
|
||||
[:put "library/images/copy" #'images/copy-image]
|
||||
[:delete "library/images/:id" #'images/delete-image]
|
||||
[:put "library/images/:id" #'images/update-image]
|
||||
[:post "library/images" #'images/create-image]
|
||||
|
||||
;; Icon Collections
|
||||
[:put "library/icon-collections/:id" #'icons/update-collection]
|
||||
[:delete "library/icon-collections/:id" #'icons/delete-collection]
|
||||
[:get "library/icon-collections" #'icons/list-collections]
|
||||
[:post "library/icon-collections" #'icons/create-collection]
|
||||
[:get "library/icon-collections/:id/icons" #'icons/list-icons]
|
||||
[:get "library/icon-collections/icons" #'icons/list-icons]
|
||||
|
||||
;; Icons
|
||||
[:put "library/icons/copy" #'icons/copy-icon]
|
||||
[:delete "library/icons/:id" #'icons/delete-icon]
|
||||
[:put "library/icons/:id" #'icons/update-icon]
|
||||
[:post "library/icons" #'icons/create-icon]
|
||||
|
||||
;; Pages
|
||||
[:put "pages/:id/metadata" #'pages/update-page-metadata]
|
||||
[:get "pages/:id/history" #'pages/retrieve-page-history]
|
||||
[:put "pages/:id/history/:hid" #'pages/update-page-history]
|
||||
[:put "pages/:id" #'pages/update-page]
|
||||
[:delete "pages/:id" #'pages/delete-page]
|
||||
[:post "pages" #'pages/create-page]
|
||||
|
||||
;; Profile
|
||||
[:get "profile/me" #'users/retrieve-profile]
|
||||
[:put "profile/me" #'users/update-profile]
|
||||
[:put "profile/me/password" #'users/update-password]
|
||||
[:post "profile/me/photo" #'users/update-photo]]]))))
|
||||
;; --- State Initialization
|
||||
|
||||
(defn- start-server
|
||||
[config]
|
||||
(let [config {:port (:http-server-port config)
|
||||
:debug (:http-server-debug config)
|
||||
:marker-file "basedir"
|
||||
:max-body-size 52428800}]
|
||||
(ct/run-server (routes config) config)))
|
||||
|
||||
;; (defstate server
|
||||
;; :start (start-server cfg/config)
|
||||
;; :stop (.stop server))
|
|
@ -1,33 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.auth
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[catacumba.core :as ct]
|
||||
[catacumba.http :as http]
|
||||
[promesa.core :as p]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.response :refer (rsp)]))
|
||||
|
||||
(s/def ::scope string?)
|
||||
(s/def ::login (s/keys :req-un [::us/username ::us/password ::scope]))
|
||||
|
||||
(defn login
|
||||
[{data :data}]
|
||||
(let [data (us/conform ::login data)
|
||||
message (assoc data :type :login)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; TODO: improve authorization
|
||||
|
||||
(defn authorization
|
||||
[{:keys [identity] :as context}]
|
||||
(if identity
|
||||
(ct/delegate {:identity (uuid/from-string (:id identity))})
|
||||
(http/forbidden (rsp nil))))
|
|
@ -1,68 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.debug-emails
|
||||
"A helper namespace for just render emails."
|
||||
(:require [clojure.edn :as edn]
|
||||
[catacumba.http :as http]
|
||||
[hiccup.page :refer (html5)]
|
||||
[uxbox.emails :as emails]
|
||||
[uxbox.emails.core :as emails-core]))
|
||||
|
||||
(def +available-emails+
|
||||
{:users/register
|
||||
{:name "Cirilla"}
|
||||
:users/password-recovery
|
||||
{:name "Cirilla"
|
||||
:token "agNFhA6SolcFb4Us2NOTNWh0cfFDquVLAav400xQPjw"}})
|
||||
|
||||
(defn- render-emails-list
|
||||
[]
|
||||
(html5
|
||||
[:section {:style "font-family: Monoid, monospace; font-size: 14px;"}
|
||||
[:h1 "Available emails"]
|
||||
[:table {:style "width: 500px;"}
|
||||
[:tbody
|
||||
[:tr
|
||||
(for [[type email] @emails-core/emails]
|
||||
[:tr
|
||||
[:td (pr-str type)]
|
||||
[:td
|
||||
[:a {:href (str "/debug/emails/email?id="
|
||||
(pr-str type)
|
||||
"&type=:text/html")}
|
||||
"(html)"]]
|
||||
[:td
|
||||
[:a {:href (str "/debug/emails/email?id="
|
||||
(pr-str type)
|
||||
"&type=:text/plain")}
|
||||
"(text)"]]])]]]]))
|
||||
|
||||
(defn list-emails
|
||||
[context]
|
||||
(http/ok (render-emails-list)
|
||||
{:content-type "text/html; charset=utf-8"}))
|
||||
|
||||
(defn- render-email
|
||||
[type content]
|
||||
(if (= type :text/html)
|
||||
content
|
||||
(html5
|
||||
[:pre content])))
|
||||
|
||||
(defn show-email
|
||||
[{params :query-params}]
|
||||
(let [id (edn/read-string (:id params))
|
||||
type (or (edn/read-string (:type params)) :text/html)
|
||||
params (-> (get +available-emails+ id)
|
||||
(assoc :email/name id))
|
||||
email (emails/render params)
|
||||
content (->> (:body email)
|
||||
(filter #(= (:uxbox.emails.core/type %) type))
|
||||
(first)
|
||||
(:content))]
|
||||
(-> (render-email type content)
|
||||
(http/ok {:content-type "text/html; charset=utf-8"}))))
|
|
@ -1,74 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.errors
|
||||
"A errors handling for frontend api."
|
||||
(:require [catacumba.core :as ct]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.util.response :refer (rsp)]))
|
||||
|
||||
(defmulti handle-exception #(:type (ex-data %)))
|
||||
|
||||
(defmethod handle-exception :validation
|
||||
[err]
|
||||
(println "\n*********** stack trace ***********")
|
||||
(.printStackTrace err)
|
||||
(println "\n********* end stack trace *********")
|
||||
(let [response (ex-data err)]
|
||||
(http/bad-request (rsp response))))
|
||||
|
||||
(defmethod handle-exception :default
|
||||
[err]
|
||||
(println "\n*********** stack trace ***********")
|
||||
(.printStackTrace err)
|
||||
(println "\n********* end stack trace *********")
|
||||
(let [response (ex-data err)]
|
||||
(http/internal-server-error (rsp response))))
|
||||
|
||||
;; --- Entry Point
|
||||
|
||||
(defn- handle-data-access-exception
|
||||
[err]
|
||||
(let [err (.getCause err)
|
||||
state (.getSQLState err)
|
||||
message (.getMessage err)]
|
||||
(case state
|
||||
"P0002"
|
||||
(-> (rsp {:message message
|
||||
:payload nil
|
||||
:type :occ})
|
||||
(http/precondition-failed))
|
||||
|
||||
(do
|
||||
(.printStackTrace err)
|
||||
(-> (rsp {:message message
|
||||
:type :unexpected
|
||||
:payload nil})
|
||||
(http/internal-server-error))))))
|
||||
|
||||
(defn- handle-unexpected-exception
|
||||
[err]
|
||||
(.printStackTrace err)
|
||||
(let [message (.getMessage err)]
|
||||
(-> (rsp {:message message
|
||||
:type :unexpected
|
||||
:payload nil})
|
||||
(http/internal-server-error))))
|
||||
|
||||
(defn handler
|
||||
[context err]
|
||||
(cond
|
||||
(instance? clojure.lang.ExceptionInfo err)
|
||||
(handle-exception err)
|
||||
|
||||
(instance? java.util.concurrent.CompletionException err)
|
||||
(handler context (.getCause err))
|
||||
|
||||
(instance? org.jooq.exception.DataAccessException err)
|
||||
(handle-data-access-exception err)
|
||||
|
||||
:else
|
||||
(handle-unexpected-exception err)))
|
|
@ -1,155 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.icons
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Constants & Config
|
||||
|
||||
(s/def ::collection (s/nilable ::us/uuid-string))
|
||||
|
||||
(s/def ::width (s/and number? pos?))
|
||||
(s/def ::height (s/and number? pos?))
|
||||
(s/def ::view-box (s/and (s/coll-of number?)
|
||||
#(= 4 (count %))
|
||||
vector?))
|
||||
|
||||
(s/def ::mimetype string?)
|
||||
(s/def ::metadata
|
||||
(s/keys :opt-un [::width ::height ::view-box ::mimetype]))
|
||||
|
||||
(s/def ::content string?)
|
||||
|
||||
;; --- Create Collection
|
||||
|
||||
(s/def ::create-collection
|
||||
(s/keys :req-un [::us/name] :opt-un [::us/id]))
|
||||
|
||||
(defn create-collection
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::create-collection data)
|
||||
message (assoc data
|
||||
:type :create-icon-collection
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [result]
|
||||
(let [loc (str "/api/library/icons/" (:id result))]
|
||||
(http/created loc (rsp result))))))))
|
||||
|
||||
;; --- Update Collection
|
||||
|
||||
(s/def ::update-collection
|
||||
(s/merge ::create-collection (s/keys :req-un [::us/version])))
|
||||
|
||||
(defn update-collection
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-collection data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-icon-collection
|
||||
:user user)]
|
||||
(-> (sv/novelty message)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Collection
|
||||
|
||||
(defn delete-collection
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-icon-collection
|
||||
:user user}]
|
||||
(-> (sv/novelty message)
|
||||
(p/then (fn [v] (http/no-content))))))
|
||||
|
||||
;; --- List collections
|
||||
|
||||
(defn list-collections
|
||||
[{user :identity}]
|
||||
(let [params {:user user
|
||||
:type :list-icon-collections}]
|
||||
(-> (sv/query params)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Create Icon
|
||||
|
||||
(s/def ::create-icon
|
||||
(s/keys :req-un [::metadata ::us/name ::metadata ::content]
|
||||
:opt-un [::us/id ::collection]))
|
||||
|
||||
(defn create-icon
|
||||
[{user :identity data :data :as request}]
|
||||
(let [{:keys [id name content metadata collection]} (us/conform ::create-icon data)
|
||||
id (or id (uuid/random))]
|
||||
(->> (sv/novelty {:id id
|
||||
:type :create-icon
|
||||
:user user
|
||||
:name name
|
||||
:collection collection
|
||||
:metadata metadata
|
||||
:content content})
|
||||
(p/map (fn [entry]
|
||||
(let [loc (str "/api/library/icons/" (:id entry))]
|
||||
(http/created loc (rsp entry))))))))
|
||||
|
||||
;; --- Update Icon
|
||||
|
||||
(s/def ::update-icon
|
||||
(s/keys :req-un [::us/name ::us/version ::collection] :opt-un [::us/id]))
|
||||
|
||||
(defn update-icon
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-icon data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-icon
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Copy Icon
|
||||
|
||||
(s/def ::copy-icon
|
||||
(s/keys :req-un [:us/id ::collection]))
|
||||
|
||||
(defn copy-icon
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::copy-icon data)
|
||||
message (assoc data
|
||||
:user user
|
||||
:type :copy-icon)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Icon
|
||||
|
||||
(defn delete-icon
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-icon
|
||||
:user user}]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [v] (http/no-content))))))
|
||||
|
||||
;; --- List collections
|
||||
|
||||
(s/def ::list-icons
|
||||
(s/keys :opt-un [::us/id]))
|
||||
|
||||
(defn list-icons
|
||||
[{user :identity route-params :route-params}]
|
||||
(let [{:keys [id]} (us/conform ::list-icons route-params)
|
||||
params {:collection id
|
||||
:type :list-icons
|
||||
:user user}]
|
||||
(->> (sv/query params)
|
||||
(p/map rsp)
|
||||
(p/map http/ok))))
|
|
@ -1,197 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.images
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[datoteka.storages :as st]
|
||||
[datoteka.core :as fs]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.images :as images]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Constants & Config
|
||||
|
||||
(s/def ::file ::us/uploaded-file)
|
||||
(s/def ::width ::us/integer-string)
|
||||
(s/def ::height ::us/integer-string)
|
||||
(s/def ::collection (s/nilable ::us/uuid-string))
|
||||
(s/def ::mimetype string?)
|
||||
|
||||
(def +thumbnail-options+ {:src :path
|
||||
:dst :thumbnail
|
||||
:width 300
|
||||
:height 100
|
||||
:quality 92
|
||||
:format "webp"})
|
||||
|
||||
(def populate-thumbnails
|
||||
#(images/populate-thumbnails % +thumbnail-options+))
|
||||
|
||||
(def populate-urls
|
||||
#(images/populate-urls % media/images-storage :path :url))
|
||||
|
||||
;; --- Create Collection
|
||||
|
||||
(s/def ::create-collection
|
||||
(s/keys :req-un [::us/name] :opt-un [::us/id]))
|
||||
|
||||
(defn create-collection
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::create-collection data)
|
||||
message (assoc data
|
||||
:type :create-image-collection
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [result]
|
||||
(let [loc (str "/api/library/images/" (:id result))]
|
||||
(http/created loc (rsp result))))))))
|
||||
|
||||
;; --- Update Collection
|
||||
|
||||
(s/def ::update-collection
|
||||
(s/merge ::create-collection (s/keys :req-un [::us/version])))
|
||||
|
||||
(defn update-collection
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-collection data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-image-collection
|
||||
:user user)]
|
||||
(-> (sv/novelty message)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Collection
|
||||
|
||||
(defn delete-collection
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-image-collection
|
||||
:user user}]
|
||||
(-> (sv/novelty message)
|
||||
(p/then (fn [v] (http/no-content))))))
|
||||
|
||||
;; --- List collections
|
||||
|
||||
(defn list-collections
|
||||
[{user :identity}]
|
||||
(let [params {:user user
|
||||
:type :list-image-collections}]
|
||||
(-> (sv/query params)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Retrieve Image
|
||||
|
||||
(s/def ::retrieve-image
|
||||
(s/keys :req-un [::us/id]))
|
||||
|
||||
(defn retrieve-image
|
||||
[{user :identity params :route-params}]
|
||||
(let [params (us/conform ::retrieve-image params)
|
||||
params (assoc params :user user :type :retrieve-image)]
|
||||
(->> (sv/query params)
|
||||
(p/map (fn [result]
|
||||
(if result
|
||||
(-> (populate-thumbnails result)
|
||||
(populate-urls)
|
||||
(rsp)
|
||||
(http/ok))
|
||||
(http/not-found "")))))))
|
||||
|
||||
;; --- Create Image
|
||||
|
||||
(s/def ::create-image
|
||||
(s/keys :req-un [::file ::width ::height ::mimetype]
|
||||
:opt-un [::us/id ::collection]))
|
||||
|
||||
(defn create-image
|
||||
[{user :identity data :data}]
|
||||
(let [{:keys [file id width height
|
||||
mimetype collection]} (us/conform ::create-image data)
|
||||
id (or id (uuid/random))
|
||||
filename (fs/name file)
|
||||
storage media/images-storage]
|
||||
(letfn [(persist-image-entry [path]
|
||||
(sv/novelty {:id id
|
||||
:type :create-image
|
||||
:user user
|
||||
:width width
|
||||
:height height
|
||||
:mimetype mimetype
|
||||
:collection collection
|
||||
:name filename
|
||||
:path (str path)}))
|
||||
(create-response [entry]
|
||||
(let [loc (str "/api/library/images/" (:id entry))]
|
||||
(http/created loc (rsp entry))))]
|
||||
(->> (st/save storage filename file)
|
||||
(p/mapcat persist-image-entry)
|
||||
(p/map populate-thumbnails)
|
||||
(p/map populate-urls)
|
||||
(p/map create-response)))))
|
||||
|
||||
;; --- Update Image
|
||||
|
||||
(s/def ::update-image
|
||||
(s/keys :req-un [::us/name ::us/version ::collection] :opt-un [::us/id]))
|
||||
|
||||
(defn update-image
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-image data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-image
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map populate-thumbnails)
|
||||
(p/map populate-urls)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Copy Image
|
||||
|
||||
(s/def ::copy-image
|
||||
(s/keys :req-un [::us/id ::collection]))
|
||||
|
||||
(defn copy-image
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::copy-image data)
|
||||
params (assoc data :user user :type :copy-image)]
|
||||
(->> (sv/novelty params)
|
||||
(p/map populate-thumbnails)
|
||||
(p/map populate-urls)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Image
|
||||
|
||||
(defn delete-image
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-image
|
||||
:user user}]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [v] (http/no-content))))))
|
||||
|
||||
;; --- List collections
|
||||
|
||||
(s/def ::list-images
|
||||
(s/keys :opt-un [::us/id]))
|
||||
|
||||
(defn list-images
|
||||
[{user :identity route-params :route-params}]
|
||||
(let [{:keys [id]} (us/conform ::list-images route-params)
|
||||
params {:collection id
|
||||
:type :list-images
|
||||
:user user}]
|
||||
(->> (sv/query params)
|
||||
(p/map (partial map populate-thumbnails))
|
||||
(p/map (partial map populate-urls))
|
||||
(p/map rsp)
|
||||
(p/map http/ok))))
|
|
@ -1,60 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.kvstore
|
||||
(:refer-clojure :exclude [update])
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
(s/def ::version integer?)
|
||||
(s/def ::key string?)
|
||||
(s/def ::value any?)
|
||||
|
||||
;; --- Retrieve
|
||||
|
||||
(s/def ::retrieve (s/keys :req-un [::key]))
|
||||
|
||||
(defn retrieve
|
||||
[{user :identity params :route-params}]
|
||||
(let [data (us/conform ::retrieve params)
|
||||
params (assoc data
|
||||
:type :retrieve-kvstore
|
||||
:user user)]
|
||||
(->> (sv/query params)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update (or Create)
|
||||
|
||||
(s/def ::update (s/keys :req-un [::key ::value]
|
||||
:opt-un [::version]))
|
||||
|
||||
(defn update
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::update data)
|
||||
params (assoc data
|
||||
:type :update-kvstore
|
||||
:user user)]
|
||||
(->> (sv/novelty params)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete
|
||||
|
||||
(s/def ::delete (s/keys :req-un [::key]))
|
||||
|
||||
(defn delete
|
||||
[{user :identity params :route-params}]
|
||||
(let [data (us/conform ::delete params)
|
||||
params (assoc data
|
||||
:type :delete-kvstore
|
||||
:user user)]
|
||||
(->> (sv/novelty params)
|
||||
(p/map (fn [_] (http/no-content))))))
|
|
@ -1,119 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.pages
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- List Pages
|
||||
|
||||
(defn list-pages-by-project
|
||||
[{user :identity params :route-params}]
|
||||
(let [params {:user user
|
||||
:project (uuid/from-string (:id params))
|
||||
:type :list-pages-by-project}]
|
||||
(-> (sv/query params)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Create Page
|
||||
|
||||
(s/def ::data any?)
|
||||
(s/def ::metadata any?)
|
||||
(s/def ::project ::us/id)
|
||||
(s/def ::create-page
|
||||
(s/keys :req-un [::data ::metadata ::project ::us/name]
|
||||
:opt-un [::us/id]))
|
||||
|
||||
(defn create-page
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::create-page data)
|
||||
message (assoc data
|
||||
:type :create-page
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [result]
|
||||
(let [loc (str "/api/pages/" (:id result))]
|
||||
(http/created loc (rsp result))))))))
|
||||
|
||||
;; --- Update Page
|
||||
|
||||
(s/def ::update-page
|
||||
(s/merge ::create-page (s/keys :req-un [::us/version])))
|
||||
|
||||
(defn update-page
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-page data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-page
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update Page Metadata
|
||||
|
||||
(s/def ::update-page-metadata
|
||||
(s/keys :req-un [::us/id ::metadata ::project ::us/name]))
|
||||
|
||||
(defn update-page-metadata
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-page-metadata data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-page-metadata
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Page
|
||||
|
||||
(defn delete-page
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-page
|
||||
:user user}]
|
||||
(-> (sv/novelty message)
|
||||
(p/then (fn [v] (http/no-content))))))
|
||||
|
||||
;; --- Retrieve Page History
|
||||
|
||||
(s/def ::max (s/and ::us/integer-string ::us/positive-integer))
|
||||
(s/def ::since ::us/integer-string)
|
||||
(s/def ::pinned ::us/boolean-string)
|
||||
|
||||
(s/def ::retrieve-page-history
|
||||
(s/keys :opt-un [::max ::since ::pinned]))
|
||||
|
||||
(defn retrieve-page-history
|
||||
[{user :identity params :route-params query :query-params}]
|
||||
(let [query (us/conform ::retrieve-page-history query)
|
||||
message (assoc query
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :list-page-history
|
||||
:user user)]
|
||||
(->> (sv/query message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update Page History
|
||||
|
||||
(s/def ::label string?)
|
||||
(s/def ::update-page-history
|
||||
(s/keys :req-un [::label ::pinned]))
|
||||
|
||||
(defn update-page-history
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-page-history data)
|
||||
message (assoc data
|
||||
:type :update-page-history
|
||||
:id (uuid/from-string (:hid params))
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
|
@ -1,73 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.projects
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- List Projects
|
||||
|
||||
(defn list-projects
|
||||
[{user :identity}]
|
||||
(let [message {:user user :type :list-projects}]
|
||||
(->> (sv/query message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Create Projects
|
||||
|
||||
(s/def ::create-project
|
||||
(s/keys :req-un [::us/name] :opt-un [::us/id]))
|
||||
|
||||
(defn create-project
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::create-project data)
|
||||
message (assoc data
|
||||
:type :create-project
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [result]
|
||||
(let [loc (str "/api/projects/" (:id result))]
|
||||
(http/created loc (rsp result))))))))
|
||||
|
||||
;; --- Update Project
|
||||
|
||||
(s/def ::update-project
|
||||
(s/keys :req-un [::us/name ::us/version]))
|
||||
|
||||
(defn update-project
|
||||
[{user :identity params :route-params data :data}]
|
||||
(let [data (us/conform ::update-project data)
|
||||
message (assoc data
|
||||
:id (uuid/from-string (:id params))
|
||||
:type :update-project
|
||||
:user user)]
|
||||
(-> (sv/novelty message)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Delete Project
|
||||
|
||||
(defn delete-project
|
||||
[{user :identity params :route-params}]
|
||||
(let [message {:id (uuid/from-string (:id params))
|
||||
:type :delete-project
|
||||
:user user}]
|
||||
(-> (sv/novelty message)
|
||||
(p/then (fn [v] (http/no-content))))))
|
||||
|
||||
|
||||
;; --- Retrieve project
|
||||
|
||||
(defn retrieve-project-by-share-token
|
||||
[{params :route-params}]
|
||||
(let [message {:token (:token params)
|
||||
:type :retrieve-project-by-share-token}]
|
||||
(->> (sv/query message)
|
||||
(p/map #(http/ok (rsp %))))))
|
|
@ -1,22 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.svgparse
|
||||
"A frontend exposed endpoints for svgparse functionality."
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
(defn parse
|
||||
[{body :body :as context}]
|
||||
(let [message {:data (slurp body)
|
||||
:type :parse-svg}]
|
||||
(->> (sv/query message)
|
||||
(p/map #(http/ok (rsp %))))))
|
|
@ -1,149 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.frontend.users
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[catacumba.http :as http]
|
||||
[datoteka.storages :as st]
|
||||
[datoteka.core :as fs]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.images :as images]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.services :as sv]
|
||||
[uxbox.services.users :as svu]
|
||||
[uxbox.util.response :refer (rsp)]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Helpers
|
||||
|
||||
(defn- resolve-thumbnail
|
||||
[user]
|
||||
(let [opts {:src :photo
|
||||
:dst :photo
|
||||
:size [100 100]
|
||||
:quality 90
|
||||
:format "jpg"}]
|
||||
(images/populate-thumbnails user opts)))
|
||||
|
||||
;; --- Retrieve Profile
|
||||
|
||||
(defn retrieve-profile
|
||||
[{user :identity}]
|
||||
(let [message {:user user
|
||||
:type :retrieve-profile}]
|
||||
(->> (sv/query message)
|
||||
(p/map resolve-thumbnail)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update Profile
|
||||
|
||||
(s/def ::fullname string?)
|
||||
(s/def ::metadata any?)
|
||||
(s/def ::update-profile
|
||||
(s/keys :req-un [::us/id ::us/username ::us/email
|
||||
::fullname ::metadata]))
|
||||
|
||||
(defn update-profile
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::update-profile data)
|
||||
message (assoc data
|
||||
:type :update-profile
|
||||
:user user)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map resolve-thumbnail)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update Password
|
||||
|
||||
(s/def ::old-password ::us/password)
|
||||
(s/def ::update-password
|
||||
(s/keys :req-un [::us/password ::old-password]))
|
||||
|
||||
(defn update-password
|
||||
[{user :identity data :data}]
|
||||
(let [data (us/conform ::update-password data)
|
||||
message (assoc data
|
||||
:type :update-profile-password
|
||||
:user user)]
|
||||
(-> (sv/novelty message)
|
||||
(p/then #(http/ok (rsp %))))))
|
||||
|
||||
;; --- Update Profile Photo
|
||||
|
||||
(s/def ::file ::us/uploaded-file)
|
||||
(s/def ::update-photo (s/keys :req-un [::file]))
|
||||
|
||||
(defn update-photo
|
||||
[{user :identity data :data}]
|
||||
(letfn [(store-photo [file]
|
||||
(let [filename (fs/name file)
|
||||
storage media/images-storage]
|
||||
(st/save storage filename file)))
|
||||
(assign-photo [path]
|
||||
(sv/novelty {:user user
|
||||
:path (str path)
|
||||
:type :update-profile-photo}))
|
||||
(create-response [_]
|
||||
(http/no-content))]
|
||||
(let [{:keys [file]} (us/conform ::update-photo data)]
|
||||
(->> (store-photo file)
|
||||
(p/mapcat assign-photo)
|
||||
(p/map create-response)))))
|
||||
|
||||
;; --- Register User
|
||||
|
||||
(s/def ::register
|
||||
(s/keys :req-un [::us/username ::us/email ::us/password ::fullname]))
|
||||
|
||||
(defn register-user
|
||||
[{data :data}]
|
||||
(let [data (us/conform ::register data)
|
||||
message (assoc data :type :register-profile)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map #(http/ok (rsp %))))))
|
||||
|
||||
|
||||
;; --- Request Password Recovery
|
||||
|
||||
;; FIXME: rename for consistency
|
||||
|
||||
(s/def ::request-recovery
|
||||
(s/keys :req-un [::us/username]))
|
||||
|
||||
(defn request-recovery
|
||||
[{data :data}]
|
||||
(let [data (us/conform ::request-recovery data)
|
||||
message (assoc data :type :request-profile-password-recovery)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [_] (http/no-content))))))
|
||||
|
||||
;; --- Password Recovery
|
||||
|
||||
;; FIXME: rename for consistency
|
||||
|
||||
(s/def ::token string?)
|
||||
(s/def ::password-recovery
|
||||
(s/keys :req-un [::token ::us/password]))
|
||||
|
||||
(defn recover-password
|
||||
[{data :data}]
|
||||
(let [data (us/conform ::password-recovery data)
|
||||
message (assoc data :type :recover-profile-password)]
|
||||
(->> (sv/novelty message)
|
||||
(p/map (fn [_] (http/no-content))))))
|
||||
|
||||
;; --- Valiadate Recovery Token
|
||||
|
||||
(defn validate-recovery-token
|
||||
[{params :route-params}]
|
||||
(let [message {:type :validate-profile-password-recovery-token
|
||||
:token (:token params)}]
|
||||
(->> (sv/query message)
|
||||
(p/map (fn [v]
|
||||
(if v
|
||||
(http/no-content)
|
||||
(http/not-found "")))))))
|
|
@ -16,8 +16,6 @@
|
|||
[uxbox.util.data :refer (dissoc-in)])
|
||||
(:import java.io.InputStream
|
||||
java.io.ByteArrayInputStream
|
||||
ratpack.form.UploadedFile
|
||||
ratpack.http.TypedData
|
||||
org.im4java.core.IMOperation
|
||||
org.im4java.core.ConvertCmd))
|
||||
|
||||
|
@ -107,27 +105,3 @@
|
|||
(dissoc-in src)
|
||||
(assoc-in dst url))))))
|
||||
|
||||
;; --- Impl
|
||||
|
||||
(extend-type UploadedFile
|
||||
pt/IPath
|
||||
(-path [this]
|
||||
(pt/-path (.getFileName ^UploadedFile this))))
|
||||
|
||||
(extend-type TypedData
|
||||
pt/IContent
|
||||
(-input-stream [this]
|
||||
(.getInputStream this))
|
||||
|
||||
io/IOFactory
|
||||
(make-reader [td opts]
|
||||
(let [^InputStream is (.getInputStream td)]
|
||||
(io/make-reader is opts)))
|
||||
(make-writer [path opts]
|
||||
(throw (UnsupportedOperationException. "read only object")))
|
||||
(make-input-stream [td opts]
|
||||
(let [^InputStream is (.getInputStream td)]
|
||||
(io/make-input-stream is opts)))
|
||||
(make-output-stream [path opts]
|
||||
(throw (UnsupportedOperationException. "read only object"))))
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[uxbox.config :as cfg]
|
||||
[uxbox.migrations]
|
||||
[uxbox.db]
|
||||
[uxbox.frontend]
|
||||
[uxbox.api]
|
||||
[uxbox.scheduled-jobs])
|
||||
(:gen-class))
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.data :as data])
|
||||
(:import ratpack.form.UploadedFile
|
||||
org.apache.commons.io.FilenameUtils))
|
||||
(:import org.apache.commons.io.FilenameUtils))
|
||||
|
||||
;; --- Helpers & Specs
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
[uxbox.util.transit :as t]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.data :as data])
|
||||
(:import ratpack.form.UploadedFile
|
||||
org.apache.commons.io.FilenameUtils))
|
||||
(:import org.apache.commons.io.FilenameUtils))
|
||||
|
||||
(s/def ::width integer?)
|
||||
(s/def ::height integer?)
|
||||
|
|
|
@ -1,73 +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/.
|
||||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.response
|
||||
"A lightweigt reponse type definition.
|
||||
|
||||
At first instance it allows set the appropriate
|
||||
content-type headers and encode the body using
|
||||
the builtin transit abstraction.
|
||||
|
||||
In future it will allow easy adapt for the content
|
||||
negotiation that is coming to catacumba."
|
||||
(:require [catacumba.impl.handlers :as ch]
|
||||
[catacumba.impl.context :as ctx]
|
||||
[buddy.core.hash :as hash]
|
||||
[buddy.core.codecs :as codecs]
|
||||
[buddy.core.codecs.base64 :as b64]
|
||||
[uxbox.util.transit :as t])
|
||||
(:import ratpack.handling.Context
|
||||
ratpack.http.Response
|
||||
ratpack.http.Request
|
||||
ratpack.http.Headers
|
||||
ratpack.http.MutableHeaders))
|
||||
|
||||
(defn digest
|
||||
[^bytes data]
|
||||
(-> (hash/blake2b-256 data)
|
||||
(b64/encode true)
|
||||
(codecs/bytes->str)))
|
||||
|
||||
(defn- etag-match?
|
||||
[^Request request ^String new-tag]
|
||||
(let [^Headers headers (.getHeaders request)]
|
||||
(when-let [etag (.get headers "if-none-match")]
|
||||
(= etag new-tag))))
|
||||
|
||||
(deftype Rsp [data]
|
||||
clojure.lang.IDeref
|
||||
(deref [_] data)
|
||||
|
||||
ch/ISend
|
||||
(-send [_ ctx]
|
||||
(let [^Response response (ctx/get-response* ctx)
|
||||
^Request request (ctx/get-request* ctx)
|
||||
^MutableHeaders headers (.getHeaders response)
|
||||
^String method (.. request getMethod getName toLowerCase)
|
||||
data (t/encode data)]
|
||||
(if (= method "get")
|
||||
(let [etag (digest data)]
|
||||
(if (etag-match? request etag)
|
||||
(do
|
||||
(.set headers "etag" etag)
|
||||
(.status response 304)
|
||||
(.send response))
|
||||
(do
|
||||
(.set headers "content-type" "application/transit+json")
|
||||
(.set headers "etag" etag)
|
||||
(ch/-send data ctx))))
|
||||
(do
|
||||
(.set headers "content-type" "application/transit+json")
|
||||
(ch/-send data ctx))))))
|
||||
|
||||
(defn rsp
|
||||
"A shortcut for create a response instance."
|
||||
[data]
|
||||
(Rsp. data))
|
||||
|
||||
(defn rsp?
|
||||
[v]
|
||||
(instance? Rsp v))
|
|
@ -104,7 +104,7 @@
|
|||
(s/def ::uuid-string (s/conformer uuid-conformer str))
|
||||
(s/def ::boolean-string (s/conformer boolean-conformer boolean-unformer))
|
||||
(s/def ::positive-integer #(< 0 % Long/MAX_VALUE))
|
||||
(s/def ::uploaded-file #(instance? ratpack.form.UploadedFile %))
|
||||
(s/def ::uploaded-file any?)
|
||||
(s/def ::uuid uuid?)
|
||||
(s/def ::bytes bytes?)
|
||||
(s/def ::path path?)
|
||||
|
|
3
backend/src/uxbox/util/struct.clj
Normal file
3
backend/src/uxbox/util/struct.clj
Normal file
|
@ -0,0 +1,3 @@
|
|||
(ns uxbox.util.struct
|
||||
(:refer-clojure :exclude [keyword uuid vector boolean long map set])
|
||||
(:require [struct.core :as st]))
|
|
@ -6,11 +6,8 @@
|
|||
|
||||
(ns uxbox.util.transit
|
||||
(:require [cognitect.transit :as t]
|
||||
[catacumba.handlers.parse :as cparse]
|
||||
[uxbox.util.time :as dt])
|
||||
(:import ratpack.http.TypedData
|
||||
ratpack.handling.Context
|
||||
java.io.ByteArrayInputStream
|
||||
(:import java.io.ByteArrayInputStream
|
||||
java.io.ByteArrayOutputStream))
|
||||
|
||||
;; --- Handlers
|
||||
|
@ -41,14 +38,6 @@
|
|||
[writer data]
|
||||
(t/write writer data))
|
||||
|
||||
|
||||
;; --- Catacumba Extension
|
||||
|
||||
(defmethod cparse/parse-body :application/transit+json
|
||||
[^Context ctx ^TypedData body]
|
||||
(let [reader (reader (.getInputStream body) {:type :json})]
|
||||
(read! reader)))
|
||||
|
||||
;; --- High-Level Api
|
||||
|
||||
(defn decode
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[buddy.hashers :as hashers]
|
||||
[buddy.core.codecs :as codecs]
|
||||
[cuerdas.core :as str]
|
||||
[catacumba.serializers :as sz]
|
||||
[ring.adapter.jetty :as jetty]
|
||||
[mount.core :as mount]
|
||||
[datoteka.storages :as st]
|
||||
|
|
Loading…
Add table
Reference in a new issue