Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

history_reads.gno

6.65 Kb · 135 lines
  1package memba_notes_v1
  2
  3import "strconv"
  4
  5func PublicHistoryInfoJSON(idHex string) string {
  6	id := historyID(idHex)
  7	h := historyGet(id)
  8	if h == nil {
  9		return "null"
 10	}
 11	n := h.Latest
 12	return `{"schema":"memba.notes.public-history-info/v1","id":` + q(idHex) + `,"start_state_revision":` + u(h.StartRevision) + `,"start_body_revision":` + u(h.StartBodyRevision) + `,"head_seq":` + u(h.Head) + `,"latest_state_revision":` + u(n.Revision) + `,"retention":"public-moderator-redactable","coverage":"public-since-publication-v1","deleted":` + strconv.FormatBool(n.Deleted) + `,"moderator_hidden":` + strconv.FormatBool(n.ModeratorHidden) + `}`
 13}
 14func historyEntryFields(e *historyEntry) string {
 15	proposal := "null"
 16	if e.Proposal != 0 {
 17		proposal = u(e.Proposal)
 18	}
 19	return `"seq":` + u(e.Seq) + `,"action":` + q(e.Action) + `,"height":` + q(strconv.FormatInt(e.Height, 10)) + `,"state_revision":` + u(e.Revision) + `,"actor":` + q(string(e.Actor)) + `,"executor":` + historyNullableText(string(e.Executor)) + `,"op_id":` + historyNullableRaw(e.Operation) + `,"proposal_id":` + proposal
 20}
 21func PublicHistoryJSON(idHex string, afterSeq, throughSeq uint64, limit int) string {
 22	id := historyID(idHex)
 23	if limit < 1 || limit > 20 {
 24		panic("notes: history page limit")
 25	}
 26	h := historyGet(id)
 27	if h == nil {
 28		return "null"
 29	}
 30	if throughSeq == 0 {
 31		if afterSeq != 0 {
 32			panic("notes: history first page cursor")
 33		}
 34		throughSeq = h.Head
 35	}
 36	if afterSeq > throughSeq || throughSeq > h.Head {
 37		panic("notes: history cursor")
 38	}
 39	items, next := "", "null"
 40	last, count := afterSeq, 0
 41	// Direct keys preserve contiguity without a scan or after+limit overflow.
 42	for last < throughSeq && count < limit {
 43		last++
 44		e := historyEntryAt(id, last)
 45		if count > 0 {
 46			items += ","
 47		}
 48		items += "{" + historyEntryFields(e) + `,"comment_id":` + historyNullableRaw(e.Comment) + "}"
 49		count++
 50	}
 51	if last < throughSeq {
 52		next = u(last)
 53	}
 54	return `{"schema":"memba.notes.public-history-page/v1","id":` + q(idHex) + `,"through_seq":` + u(throughSeq) + `,"items":[` + items + `],"next_cursor":` + next + `}`
 55}
 56func PublicHistoryEntryJSON(idHex string, seq uint64) string {
 57	v, ok := historyEntries.Get(historyKey(historyID(idHex), seq))
 58	if !ok {
 59		return "null"
 60	}
 61	e := v.(*historyEntry)
 62	return `{"schema":"memba.notes.public-history-entry/v1","id":` + q(idHex) + "," + historyEntryFields(e) + `,"governance_action":` + historyNullableText(e.GovernanceAction) + `,"detail":` + e.Detail + `}`
 63}
 64
 65// PublicHistoryVersionJSON reads the public state recorded at a state revision.
 66// recorded_seq is the event that recorded it; PublicHistoryBodyChunkJSON and
 67// RedactPublicContentAtSeq address that version by this seq.
 68func PublicHistoryVersionJSON(idHex string, stateRevision uint64) string {
 69	id := historyID(idHex)
 70	h := historyGet(id)
 71	if h == nil {
 72		return "null"
 73	}
 74	e := historyRevisionEntry(id, h, stateRevision)
 75	if e == nil {
 76		return "null"
 77	}
 78	v := e.Version
 79	titleRevision, title, bodyRevision, bodyHash, bodyBytes := "null", "null", "null", "null", "0"
 80	titleRedacted, bodyRedacted := false, false
 81	if v.Title != nil {
 82		titleRevision, titleRedacted = u(v.TitleRevision), v.Title.Redacted
 83		if !titleRedacted {
 84			title = blob(v.Title.Bytes)
 85		}
 86	}
 87	if v.Body != nil {
 88		bodyRevision, bodyHash, bodyBytes, bodyRedacted = u(v.BodyRevision), q(v.Body.Hash), strconv.Itoa(len(v.Body.Bytes)), v.Body.Redacted
 89	}
 90	writers := ""
 91	for i, who := range v.Writers {
 92		if i > 0 {
 93			writers += ","
 94		}
 95		writers += q(string(who))
 96	}
 97	return `{"schema":"memba.notes.public-history-version/v1","id":` + q(idHex) + `,"state_revision":` + u(v.Revision) + `,"recorded_seq":` + u(e.Seq) + `,"owner":` + q(string(v.Owner)) + `,"pending_owner":` + historyNullableText(string(v.PendingOwner)) + `,"owner_is_realm":` + strconv.FormatBool(v.OwnerIsRealm) + `,"owner_generation":` + u(v.OwnerGeneration) + `,"mode":` + strconv.Itoa(int(v.Mode)) + `,"epoch":` + u(uint64(v.Epoch)) + `,"title_revision":` + titleRevision + `,"title_blob":` + title + `,"title_redacted":` + strconv.FormatBool(titleRedacted) + `,"body_revision":` + bodyRevision + `,"body_bytes":` + q(bodyBytes) + `,"body_sha256":` + bodyHash + `,"body_redacted":` + strconv.FormatBool(bodyRedacted) + `,"writers":[` + writers + `],"policies":{"read":` + q(v.PolicyRead) + `,"write":` + q(v.PolicyWrite) + `,"comment":` + q(v.PolicyComment) + `},"gov_writers":` + strconv.FormatBool(v.GovWriters) + `,"allow_public_writes":` + strconv.FormatBool(v.PublicWrites) + `,"owner_listed":` + strconv.FormatBool(v.Listed) + `,"moderator_hidden":` + strconv.FormatBool(v.ModeratorHidden) + `,"deleted":` + strconv.FormatBool(v.Deleted) + `}`
 98}
 99
100// PublicHistoryBodyChunkJSON reads the body of the version recorded by the
101// note-level event seq (a version's recorded_seq). A later note-level event
102// that kept the body returns the same body; comment and cleanup events, deletion
103// versions, unknown seqs and redacted bodies return null.
104func PublicHistoryBodyChunkJSON(idHex string, seq uint64, offset, limit int) string {
105	id := historyID(idHex)
106	if limit < 1 || limit > MaxBodyChunkBytes || offset < 0 {
107		panic("notes: history chunk bounds")
108	}
109	v := historyVersionAt(id, seq)
110	if v == nil || v.Body == nil {
111		return "null"
112	}
113	b := v.Body
114	if b.Redacted {
115		return "null"
116	}
117	if offset > len(b.Bytes) {
118		panic("notes: history chunk bounds")
119	}
120	end := offset + limit
121	if end > len(b.Bytes) {
122		end = len(b.Bytes)
123	}
124	return `{"schema":"memba.notes.public-history-body/v2","id":` + q(idHex) + `,"seq":` + u(seq) + `,"body_revision":` + u(v.BodyRevision) + `,"sha256":` + q(b.Hash) + `,"offset":` + q(strconv.Itoa(offset)) + `,"total":` + q(strconv.Itoa(len(b.Bytes))) + `,"next_offset":` + q(strconv.Itoa(end)) + `,"chunk_blob":` + blob(b.Bytes[offset:end]) + `}`
125}
126func PublicHistoryCommentJSON(idHex, cidHex string) string {
127	id, cid := historyID(idHex), historyID(cidHex)
128	v, ok := historyComments.Get(commentKey(id, cid))
129	if !ok {
130		return "null"
131	}
132	h := v.(*historyComment)
133	// The reference describes the first version: revision 1, not yet deleted, hidden or resolved.
134	return `{"schema":"memba.notes.public-history-comment/v1","id":` + q(idHex) + `,"comment_id":` + q(cidHex) + `,"content":{"author":` + q(string(h.Author)) + `,"created_height":` + q(strconv.FormatInt(h.CreatedHeight, 10)) + `,"epoch":` + u(uint64(h.Epoch)) + `,"anchor_blob":` + blob(h.Anchor) + `,"body_blob":` + blob(h.Body) + `,"reference":` + historyCommentDetail(cidHex, h.Parent, 1, h.BodyRevision, false, false, false, h) + `},"presentation":{"latest_seq":` + u(h.LatestSeq) + `,"deleted":` + strconv.FormatBool(h.Deleted) + `,"hidden":` + strconv.FormatBool(h.Hidden) + `,"resolved":` + strconv.FormatBool(h.Resolved) + `,"redacted":` + strconv.FormatBool(h.Redacted) + `}}`
135}