add user page

This commit is contained in:
Tienson Qin
2025-12-29 23:10:45 +08:00
parent 9dab647d04
commit be69c009d9
4 changed files with 100 additions and 21 deletions

View File

@@ -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)}))))

View File

@@ -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 "<!doctype html>" (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 "<!doctype html>" (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)]]]]

View File

@@ -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

View File

@@ -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)))