Edit lock acquisition

This commit is contained in:
2026-05-16 23:05:42 +02:00
parent 8da3f42c2f
commit 3dc69bb070
3 changed files with 184 additions and 7 deletions
+55 -3
View File
@@ -197,11 +197,11 @@ func DeployWikiWithOptions(p *project.Project, opts DeployWikiOptions, progress
entry.PID = created.PID
nextManifest.Pages[plan.Page.PageID] = entry
case "update":
if err := client.updatePost(plan.Entry.PID, plan.Content, summary); err != nil {
if err := client.updatePost(plan.Entry.TID, plan.Entry.PID, plan.Content, summary); err != nil {
return result, err
}
case "archive":
if err := client.updatePost(plan.Entry.PID, plan.Content, summary); err != nil {
if err := client.updatePost(plan.Entry.TID, plan.Entry.PID, plan.Content, summary); err != nil {
return result, err
}
}
@@ -378,6 +378,10 @@ func planNodeBBDeploy(pages map[string]wikiDeployPage, manifest wikiDeployManife
if err != nil {
return nil, result, next, err
}
if entry.TID == 0 && remote.TID != 0 {
entry.TID = remote.TID
next.Pages[pageID] = entry
}
remoteHash := computeManagedHash(remote.Content)
if manifest.Pages[pageID].Hash != "" && remoteHash != manifest.Pages[pageID].Hash {
result.Drifted++
@@ -823,6 +827,10 @@ type nodeBBPost struct {
Content string
}
type nodeBBEditLock struct {
Token string
}
type nodeBBWikiPage struct {
TID int
Title string
@@ -896,14 +904,44 @@ func (c *nodeBBClient) createTopic(cid int, title, content, summary string) (nod
return post, nil
}
func (c *nodeBBClient) updatePost(pid int, content, summary string) error {
func (c *nodeBBClient) updatePost(tid, pid int, content, summary string) error {
if tid == 0 {
post, err := c.getPost(pid)
if err != nil {
return err
}
tid = post.TID
}
lock, err := c.acquireEditLock(tid)
if err != nil {
return err
}
body := map[string]any{"content": content}
if lock.Token != "" {
body["wikiEditLockToken"] = lock.Token
}
if summary != "" {
body["_uid_note"] = summary
}
return c.request("PUT", fmt.Sprintf("/api/v3/posts/%d", pid), body, nil)
}
func (c *nodeBBClient) acquireEditLock(tid int) (nodeBBEditLock, error) {
if tid == 0 {
return nodeBBEditLock{}, fmt.Errorf("NodeBB wiki post update requires a topic id for edit locking")
}
body := map[string]any{"tid": tid}
var doc any
if err := c.request("PUT", "/api/v3/plugins/westgate-wiki/edit-lock", body, &doc); err != nil {
return nodeBBEditLock{}, err
}
lock := parseNodeBBEditLock(doc)
if lock.Token == "" {
return nodeBBEditLock{}, fmt.Errorf("NodeBB wiki edit lock response for topic %d did not include token", tid)
}
return lock, nil
}
func (c *nodeBBClient) request(method, path string, payload any, out any) error {
var body io.Reader
if payload != nil {
@@ -973,6 +1011,20 @@ func parseNodeBBPost(doc any) nodeBBPost {
}
}
func parseNodeBBEditLock(doc any) nodeBBEditLock {
for {
m, ok := doc.(map[string]any)
if !ok {
return nodeBBEditLock{}
}
if response, ok := m["response"]; ok {
doc = response
continue
}
return nodeBBEditLock{Token: firstString(m, "token")}
}
}
func parseNodeBBWikiPageList(doc any) ([]nodeBBWikiPage, string, bool) {
for {
m, ok := doc.(map[string]any)