From be69c009d9bdc2ec23f8d31d247ff7cd334ce2df Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 29 Dec 2025 23:10:45 +0800 Subject: [PATCH] add user page --- .../src/logseq/publish/meta_store.cljs | 27 ++++++-- deps/publish/src/logseq/publish/render.cljs | 61 ++++++++++++++----- deps/publish/src/logseq/publish/routes.cljs | 30 ++++++++- src/main/frontend/handler/publish.cljs | 3 + 4 files changed, 100 insertions(+), 21 deletions(-) diff --git a/deps/publish/src/logseq/publish/meta_store.cljs b/deps/publish/src/logseq/publish/meta_store.cljs index 535fd4d5d6..2d3a566e66 100644 --- a/deps/publish/src/logseq/publish/meta_store.cljs +++ b/deps/publish/src/logseq/publish/meta_store.cljs @@ -20,6 +20,7 @@ "content_length INTEGER," "r2_key TEXT NOT NULL," "owner_sub TEXT," + "owner_username TEXT," "created_at INTEGER," "updated_at INTEGER," "password_hash TEXT," @@ -33,6 +34,8 @@ (publish-common/sql-exec sql "ALTER TABLE pages ADD COLUMN page_tags TEXT;")) (when-not (contains? col-names "short_id") (publish-common/sql-exec sql "ALTER TABLE pages ADD COLUMN short_id TEXT;")) + (when-not (contains? col-names "owner_username") + (publish-common/sql-exec sql "ALTER TABLE pages ADD COLUMN owner_username TEXT;")) (when-not (contains? col-names "password_hash") (publish-common/sql-exec sql "ALTER TABLE pages ADD COLUMN password_hash TEXT;"))) (let [cols (publish-common/get-sql-rows (publish-common/sql-exec sql "PRAGMA table_info(page_refs);")) @@ -110,11 +113,12 @@ "content_length," "r2_key," "owner_sub," + "owner_username," "created_at," "updated_at," "short_id," "password_hash" - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" " ON CONFLICT(graph_uuid, page_uuid) DO UPDATE SET" " page_uuid=excluded.page_uuid," " page_title=excluded.page_title," @@ -125,6 +129,7 @@ " content_length=excluded.content_length," " r2_key=excluded.r2_key," " owner_sub=excluded.owner_sub," + " owner_username=excluded.owner_username," " updated_at=excluded.updated_at," " short_id=excluded.short_id," " password_hash=excluded.password_hash;") @@ -138,6 +143,7 @@ (aget body "content_length") (aget body "r2_key") (aget body "owner_sub") + (aget body "owner_username") (aget body "created_at") (aget body "updated_at") (aget body "short_id") @@ -250,6 +256,19 @@ row (first rows)] (publish-common/json-response {:page (when row (js->clj row :keywordize-keys false))})) + (= (nth parts 1 nil) "user") + (let [raw-username (nth parts 2 nil) + username (when raw-username (js/decodeURIComponent raw-username)) + rows (publish-common/get-sql-rows + (publish-common/sql-exec sql + (str "SELECT page_uuid, page_title, short_id, graph_uuid, updated_at, owner_username " + "FROM pages WHERE owner_username = ? ORDER BY updated_at DESC;") + username))] + (publish-common/json-response {:user {:username username} + :pages (map (fn [row] + (js->clj row :keywordize-keys false)) + rows)})) + (= (nth parts 4 nil) "password") (let [rows (publish-common/get-sql-rows (publish-common/sql-exec sql @@ -294,7 +313,7 @@ (let [rows (publish-common/get-sql-rows (publish-common/sql-exec sql (str "SELECT page_uuid, page_title, page_tags, short_id, graph_uuid, schema_version, block_count, " - "content_hash, content_length, r2_key, owner_sub, created_at, updated_at " + "content_hash, content_length, r2_key, owner_sub, owner_username, created_at, updated_at " "FROM pages WHERE graph_uuid = ? AND page_uuid = ? LIMIT 1;") graph-uuid page-uuid)) @@ -307,7 +326,7 @@ (let [rows (publish-common/get-sql-rows (publish-common/sql-exec sql (str "SELECT page_uuid, page_title, page_tags, short_id, graph_uuid, schema_version, block_count, " - "content_hash, content_length, r2_key, owner_sub, created_at, updated_at " + "content_hash, content_length, r2_key, owner_sub, owner_username, created_at, updated_at " "FROM pages WHERE graph_uuid = ? ORDER BY updated_at DESC;") graph-uuid))] (publish-common/json-response {:pages (map row->meta rows)})) @@ -316,7 +335,7 @@ (let [rows (publish-common/get-sql-rows (publish-common/sql-exec sql (str "SELECT page_uuid, page_title, page_tags, short_id, graph_uuid, schema_version, block_count, " - "content_hash, content_length, r2_key, owner_sub, created_at, updated_at " + "content_hash, content_length, r2_key, owner_sub, owner_username, created_at, updated_at " "FROM pages ORDER BY updated_at DESC;")))] (publish-common/json-response {:pages (map row->meta rows)})))) diff --git a/deps/publish/src/logseq/publish/render.cljs b/deps/publish/src/logseq/publish/render.cljs index 7b25b4ff73..ccb5691880 100644 --- a/deps/publish/src/logseq/publish/render.cljs +++ b/deps/publish/src/logseq/publish/render.cljs @@ -9,7 +9,7 @@ [logseq.publish.common :as publish-common] [logseq.publish.model :as publish-model])) -(defonce version 1767019463259) +(defonce version 1767021063531) (def ref-regex (js/RegExp. "\\[\\[([0-9a-fA-F-]{36})\\]\\]|\\(\\(([0-9a-fA-F-]{36})\\)\\)" "g")) @@ -1192,18 +1192,55 @@ [:h1 "Published pages"] (if (seq rows) [:ul.page-list - (for [{:keys [page-uuid page-title href updated-at short-id]} rows] + (for [{:keys [page-uuid page-title href updated-at]} rows] [:li.page-item [:div.page-links - [:a.page-link {:href href} (or page-title page-uuid)] - (when short-id - [:a.short-link {:href (str "/s/" short-id)} - (str "/s/" short-id)])] + [:a.page-link {:href href} (or page-title page-uuid)]] [:span.page-meta (or (format-timestamp updated-at) "—")]])] [:p "No pages have been published yet."]) (publish-script)]]]] (str "" (render-hiccup doc)))) +(defn render-user-html + [username user pages] + (let [username (or (aget user "username") username) + rows (->> pages + (map (fn [page] + (let [page-uuid (aget page "page_uuid") + page-title (aget page "page_title") + updated-at (aget page "updated_at") + graph-uuid (aget page "graph_uuid") + href (str "/page/" graph-uuid "/" page-uuid) + short-id (aget page "short_id")] + {:page-uuid page-uuid + :page-title page-title + :href href + :short-id short-id + :updated-at updated-at + :graph-uuid graph-uuid}))) + (sort-by (fn [row] + (or (:updated-at row) 0))) + reverse) + title (str "Published by " username) + doc [:html + (head-node title nil) + [:body + [:main.wrap + (toolbar-node + (theme-toggle-node)) + [:h1 title] + (if (seq rows) + [:ul.page-list + (for [{:keys [page-uuid page-title href updated-at]} rows] + [:li.page-item + [:div.page-links + [:a.page-link {:href href} (or page-title page-uuid)]] + [:span.page-meta + (or (format-timestamp updated-at) "—")]])] + [:p "No pages have been published yet."]) + (publish-script)]]]] + (str "" (render-hiccup doc)))) + (defn render-tag-html [graph-uuid tag-uuid tag-title tag-items] (let [rows tag-items @@ -1245,17 +1282,13 @@ :let [graph-id (tag-item-val row :graph_uuid) page-uuid (tag-item-val row :source_page_uuid) page-title (tag-item-val row :source_page_title) - short-id (tag-item-val row :short_id) href (when (and graph-id page-uuid) (str "/page/" graph-id "/" page-uuid))]] [:li.page-item [:div.page-links (if href [:a.page-ref {:href href} (or page-title page-uuid)] - [:span (or page-title page-uuid)]) - (when short-id - [:a.short-link {:href (str "/s/" short-id)} - (str "/s/" short-id)])] + [:span (or page-title page-uuid)])] [:span.page-meta (or (format-timestamp (tag-item-val row :updated_at)) "—")]])] [:p "No published pages use this tag yet."]) (publish-script)]]]] @@ -1281,17 +1314,13 @@ :let [graph-id (or (tag-item-val row :graph_uuid) graph-uuid) page-uuid (tag-item-val row :source_page_uuid) page-title (tag-item-val row :source_page_title) - short-id (tag-item-val row :short_id) href (when (and graph-id page-uuid) (str "/page/" graph-id "/" page-uuid))]] [:li.page-item [:div.page-links (if href [:a.page-ref {:href href} (or page-title page-uuid)] - [:span (or page-title page-uuid)]) - (when short-id - [:a.short-link {:href (str "/s/" short-id)} - (str "/s/" short-id)])] + [:span (or page-title page-uuid)])] [:span.page-meta (or (format-timestamp (tag-item-val row :updated_at)) "—")]])] [:p "No published pages reference this yet."]) (publish-script)]]]] diff --git a/deps/publish/src/logseq/publish/routes.cljs b/deps/publish/src/logseq/publish/routes.cljs index 11f63144c4..cd6bf395f7 100644 --- a/deps/publish/src/logseq/publish/routes.cljs +++ b/deps/publish/src/logseq/publish/routes.cljs @@ -96,6 +96,12 @@ page-tags (or (:page-tags payload) (get payload "page-tags")) short-id (publish-common/short-id-for-page graph-uuid page_uuid) + owner-sub (:owner_sub meta) + owner-username (:owner_username meta) + _ (when-not (and owner-sub owner-username) + (throw (ex-info "owner sub or username is missing" + {:owner-sub owner-sub + :owner-username owner-username}))) payload (clj->js {:page_uuid page_uuid :page_title page-title :page_tags (when page-tags @@ -107,7 +113,8 @@ :content_hash content_hash :content_length content_length :r2_key r2-key - :owner_sub (aget claims "sub") + :owner_sub owner-sub + :owner_username owner-username :created_at created_at :updated_at (.now js/Date) :short_id short-id @@ -649,6 +656,27 @@ #js {"location" location} (publish-common/cors-headers))})))))))) + (and (string/starts-with? path "/u/") (= method "GET")) + (let [parts (string/split path #"/") + username (nth parts 2 nil)] + (if (string/blank? username) + (publish-common/bad-request "missing username") + (js-await [^js do-ns (aget env "PUBLISH_META_DO") + index-id (.idFromName do-ns "index") + index-stub (.get do-ns index-id) + resp (.fetch index-stub (str "https://publish/user/" username) + #js {:method "GET"})] + (if-not (.-ok resp) + (publish-common/not-found) + (js-await [data (.json resp) + user (aget data "user") + rows (or (aget data "pages") #js [])] + (js/Response. + (publish-render/render-user-html username user rows) + #js {:headers (publish-common/merge-headers + #js {"content-type" "text/html; charset=utf-8"} + (publish-common/cors-headers))})))))) + (and (string/starts-with? path "/pages/") (= method "GET")) (let [parts (string/split path #"/")] (cond diff --git a/src/main/frontend/handler/publish.cljs b/src/main/frontend/handler/publish.cljs index be4887e33f..d5f646b929 100644 --- a/src/main/frontend/handler/publish.cljs +++ b/src/main/frontend/handler/publish.cljs @@ -7,6 +7,7 @@ [frontend.fs :as fs] [frontend.handler.notification :as notification] [frontend.handler.property :as property-handler] + [frontend.handler.user :as user-handler] [frontend.image :as image] [frontend.state :as state] [frontend.util :as util] @@ -301,6 +302,8 @@ :compression :none :content_hash content-hash :content_length (count body) + :owner_sub (user-handler/user-uuid) + :owner_username (user-handler/username) :created_at (util/time-ms)} publish-body (assoc payload :meta publish-meta) headers (assoc headers "x-publish-meta" (js/JSON.stringify (clj->js publish-meta)))