summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-05-09 13:39:09 +0800
committereltrac <hi@eltr.ac>2026-05-09 13:39:09 +0800
commit9ba4e64e19890a17adb9e73ea6453997f3cbab18 (patch)
tree28be67636c12de3e8c90cf4beb0ed3be04b0b744 /src
parent1d1859e523f7502f8ff226aea105dc15c4b0ff73 (diff)
feat(API): response paging
Diffstat (limited to 'src')
-rw-r--r--src/weepinbell/handler.clj8
-rw-r--r--src/weepinbell/retriever.clj72
2 files changed, 44 insertions, 36 deletions
diff --git a/src/weepinbell/handler.clj b/src/weepinbell/handler.clj
index a4b69fc..0040fcd 100644
--- a/src/weepinbell/handler.clj
+++ b/src/weepinbell/handler.clj
@@ -15,13 +15,13 @@
(defmacro defmention-routes [base-path mention-type]
`(context ~base-path []
- (GET "/" [~'url] (retriever/by-url ~'url ~mention-type))
- (GET "/:domain" [~'domain] (retriever/by-domain ~'domain ~mention-type))))
+ (GET "/" [~'url ~'page] (retriever/by-url ~'url ~mention-type ~'page))
+ (GET "/:domain" [~'domain ~'page] (retriever/by-domain ~'domain ~mention-type ~'page))))
(defroutes api-routes
(GET "/" [target] (ui/home (get-config :allowed-target-domains)
- (get-config :endpoint)
- target))
+ (get-config :endpoint)
+ target))
;; receiver endpoint
(POST (get-config :endpoint) [source target]
(receive {:s source :t target} wmc))
diff --git a/src/weepinbell/retriever.clj b/src/weepinbell/retriever.clj
index 20ff686..de0d436 100644
--- a/src/weepinbell/retriever.clj
+++ b/src/weepinbell/retriever.clj
@@ -3,10 +3,12 @@
[weepinbell.utils :refer [get-domain]]
[weepinbell.microformats-wrapper :as mf-wrapper]))
+(def default-page-size 12)
+
;; utilities
(defn- respond-webmention-json [data]
- (if data
- {:status 200
+ (if data
+ {:status 200
:headers {"Content-Type" "application/json; charset=utf-8"}
:body data}
;; if no data found, respond 404
@@ -15,20 +17,30 @@
:body {:status 404
:message "Webmention does not exist or is pending for verification."}}))
-(defn- respond-webmention-list-json [data]
- {:status 200
- :headers {"Content-Type" "application/json; charset=utf-8"}
- :body data})
+(defn- respond-webmention-list-json
+ ([data]
+ (respond-webmention-list-json nil nil data))
+ ([page data]
+ (respond-webmention-list-json page default-page-size data))
+ ([page page-size data]
+ (let [page (Integer/parseInt page)]
+ {:status 200
+ :headers {"Content-Type" "application/json; charset=utf-8"}
+ :body (if (or (nil? page) (< page 0)) data
+ ;; if page number is provided
+ ;; partition and return page frame
+ (-> (partition-all page-size data)
+ (nth page)))})))
(defn- wrap-response-object [data]
(let [result {:webmention (:webmention data)}]
(cond-> result
(not (empty? (:microformats data)))
- (assoc :microformats (-> data
- :microformats
- mf-wrapper/wrap-entry))
+ (assoc :microformats (-> data
+ :microformats
+ mf-wrapper/wrap-entry))
(:extra data)
- (assoc :extra (:extra data)))))
+ (assoc :extra (:extra data)))))
(defn- wrap-response-list [data]
(map wrap-response-object data))
@@ -48,31 +60,27 @@
(defn by-domain
"Get webmentions sent to a particular domain."
- ([domain]
- (by-domain domain nil))
- ([domain typ]
- (cond->> (storage/get-wms-by-domain domain)
- true wrap-response-list
- typ (filter-response-by-mftype typ)
- true respond-webmention-list-json)))
+ [domain typ page]
+ (cond->> (storage/get-wms-by-domain domain)
+ true wrap-response-list
+ typ (filter-response-by-mftype typ)
+ true (respond-webmention-list-json page)))
(defn by-url
"Get webmention sent to a particular URL."
- ([url]
- (by-url url nil))
- ([url typ]
- (if url
- (cond->> (get-domain url)
- true storage/get-wms-by-domain
- true (filter #(= url (get-in % [:webmention :target])))
- true wrap-response-list
- typ (filter-response-by-mftype typ)
- true respond-webmention-list-json)
- ;; if no url query is passed
- {:status 400
- :headers {"Content-Type" "application/json; charset=utf-8"}
- :body {:status 400
- :message "Missing URL. Specify target URL whose webmentions you are querying."}})))
+ [url typ page]
+ (if url
+ (cond->> (get-domain url)
+ true storage/get-wms-by-domain
+ true (filter #(= url (get-in % [:webmention :target])))
+ true wrap-response-list
+ typ (filter-response-by-mftype typ)
+ true (respond-webmention-list-json page))
+ ;; if no url query is passed
+ {:status 400
+ :headers {"Content-Type" "application/json; charset=utf-8"}
+ :body {:status 400
+ :message "Missing URL. Specify target URL whose webmentions you are querying."}}))
(defn by-id
"Get one specific webmention by ID."