diff options
| author | polwex <polwex@sortug.com> | 2025-10-06 01:01:41 +0700 |
|---|---|---|
| committer | polwex <polwex@sortug.com> | 2025-10-06 01:01:41 +0700 |
| commit | c4b392a179048f936c062f5ffccc2bc25627e500 (patch) | |
| tree | 09be0904be8ec4d7ea52992ef7580d42ed0c28c1 /app/lib/trill | |
working
Diffstat (limited to 'app/lib/trill')
| -rw-r--r-- | app/lib/trill/feed.hoon | 70 | ||||
| -rw-r--r-- | app/lib/trill/gate.hoon | 79 | ||||
| -rw-r--r-- | app/lib/trill/post.hoon | 379 |
3 files changed, 528 insertions, 0 deletions
diff --git a/app/lib/trill/feed.hoon b/app/lib/trill/feed.hoon new file mode 100644 index 0000000..721a596 --- /dev/null +++ b/app/lib/trill/feed.hoon @@ -0,0 +1,70 @@ +/- feed=trill-feed, post=trill-post, sur=nostrill +/+ sr=sortug, constants +|% +++ latest-page +=/ count feed-page-size:constants +|= f=feed:feed ^- fc:feed + =/ nodelist (tap:orm:feed f) + =/ subset (scag count nodelist) + ?~ subset [f ~ ~] + =/ start `-.i.subset + =/ rev (flop subset) + ?~ rev [f ~ ~] + =/ end `-.i.rev + =/ nf (gas:orm:feed *feed:feed subset) + [nf start end] +:: +++ latest-page-nostr |= f=nostr-feed:sur ^- nfc:sur + =/ nodelist (tap:norm:sur f) + =/ subset (scag feed-page-size:constants nodelist) + ?~ subset [f ~ ~] + =/ start (some `@da`-.i.subset) + =/ rev (flop subset) + ?~ rev [f ~ ~] + =/ end (some `@da`-.i.rev) + =/ nf (gas:norm:sur *nostr-feed:sur subset) + [nf start end] +:: +:: NOTE START IS OLD, END IS NEW + +++ subset +=/ count feed-page-size:constants +|= [=fc:feed replies=? now=@da] ^- fc:feed + ?: ?&(?=(%~ start.fc) ?=(%~ end.fc)) (latest-page feed.fc) + + =/ start ?~ start.fc 0 u.start.fc + =/ end ?~ end.fc now u.end.fc + =/ nodelist (tap:orm:feed feed.fc) + + =/ threads %+ skim nodelist + |= [=id:post =post:post] ^- ? + ?. replies + ?& + ?= %~ parent.post + (lte id start) (gte id end) + == + ?& (lte id start) (gte id end) == + =/ thread-count (lent threads) + :: TODO I remember something was weird about this + :: =/ result=(list [id:post post:post]) ?: newest (scag count threads) (flop (scag count (flop threads))) + =/ result=(list [id:post post:post]) (scag count threads) + =/ cursors=[(unit @da) (unit @da)] ?~ result [~ ~] ?~ threads [~ ~] :- + ?: .=((head result) (head threads)) ~ `id:(head result) + ?: .=((rear result) (rear threads)) ~ `id:(rear result) + [(gas:orm:feed *feed:feed result) -.cursors +.cursors] +:: posts +++ node-to-full +|= [p=post:post f=feed:feed] ^- full-node:post + p(children (convert-children children.p f)) +++ convert-children +|= [children=(set id:post) f=feed:feed] + ^- internal-graph:post + =/ g=full-graph:post %- ~(rep in children) + |= [=id:post acc=full-graph:post] + =/ n (get:orm:feed f id) + ?~ n acc + =/ full-node (node-to-full u.n f) + (put:form:post acc id full-node) + ?~ children [%empty ~] + :- %full g +-- diff --git a/app/lib/trill/gate.hoon b/app/lib/trill/gate.hoon new file mode 100644 index 0000000..ebb78b8 --- /dev/null +++ b/app/lib/trill/gate.hoon @@ -0,0 +1,79 @@ +/- gate=trill-gate +|% +++ mask-lock +|= =lock:gate ^- lock:gate + :* ?: public.rank.lock rank.lock [~ %| %|] + ?: public.luk.lock luk.lock [~ %| %|] + ?: public.ship.lock ship.lock [~ %| %|] + ?: public.tags.lock tags.lock [~ %| %|] + ?: public.custom.lock custom.lock [~ %|] + == +++ can-access +|= [=ship =lock:gate =bowl:gall] ^- ? + ?^ fn.custom.lock %- u.fn.custom.lock ship + =/ in-luk (~(has in caveats.ship.lock) ship) + =/ fu (sein:title our.bowl now.bowl ship) + =/ ye (sein:title our.bowl now.bowl fu) + =/ ze (sein:title our.bowl now.bowl ye) + =/ in-ship ?| + (~(has in caveats.luk.lock) fu) + (~(has in caveats.luk.lock) ye) + (~(has in caveats.luk.lock) ze) + == + =/ in-rank (~(has in caveats.rank.lock) (clan:title ship)) + :: =/ in-tags (~(has in (scry-pals-tags caveats.tags.lock)) ship) + =/ can |= [pit=? has=?] ^- ? ?: pit has !has + =/ as-ship (can locked.ship.lock in-ship) + =/ as-luk (can locked.ship.lock in-luk) + =/ as-rank (can locked.ship.lock in-rank) + ::=/ as-tags (can locked.ship.lock in-tags) + ?&(as-ship as-luk as-rank) + +++ scry-pals-tags +|= tags=(set @t) ^- (set @p) + :: .^() + ~ +++ apply-change +|= [=lock:gate =change:gate] ^- lock:gate + ?- -.change + %set-rank lock(rank +.change) + %set-luk lock(luk +.change) + %set-ship lock(ship +.change) + %set-tags lock(tags +.change) + %set-custom lock ::TODO + == +++ open-all +|= =lock:gate ^- lock:gate + %= lock + rank rank.lock(locked .n) + luk luk.lock(locked .n) + ship ship.lock(locked .n) + tags tags.lock(locked .n) + == +++ lock-all +|= =lock:gate ^- lock:gate +%= lock +rank rank.lock(locked .y) +luk luk.lock(locked .y) +ship ship.lock(locked .y) +tags tags.lock(locked .y) +== +++ toggle-rank +|= [r=rank:title setting=[caveats=(set rank:title) locked=? public=?]] + =/ new-caveats=(set rank:title) ?: locked.setting + (~(put in caveats.setting) r) + (~(del in caveats.setting) r) + setting(caveats new-caveats) +++ toggle-ship +|= [s=ship setting=[caveats=(set ship) locked=? public=?]] + =/ new-caveats=(set ship) ?: locked.setting + (~(put in caveats.setting) s) + (~(del in caveats.setting) s) + setting(caveats new-caveats) +++ toggle-tag +|= [t=@t setting=[caveats=(set @t) locked=? public=?]] + =/ new-caveats=(set @t) ?: locked.setting + (~(put in caveats.setting) t) + (~(del in caveats.setting) t) + setting(caveats new-caveats) +-- diff --git a/app/lib/trill/post.hoon b/app/lib/trill/post.hoon new file mode 100644 index 0000000..968bcad --- /dev/null +++ b/app/lib/trill/post.hoon @@ -0,0 +1,379 @@ +/- tp=trill-post, md=markdown +/+ sr=sortug, mdlib=markdown +|% +++ build-sp + |= [host=@p author=@p input=@t parent=(unit @) thread=(unit @)] + ^- sent-post:tp + =/ cl (tokenise input) + ~| "parsing error!!" + ?: ?=(%| -.cl) !! + =| sp=sent-post:tp + %= sp + host host + author author + contents +.cl + parent parent + thread thread + == +++ build-post + |= [now=@da pubkey=@ux sp=sent-post:tp] + ^- post:tp + =/ cm (init-content-map contents.sp now) + =/ thread ?~ thread.sp now u.thread.sp + =/ =post:tp + :* id=now + host.sp + author.sp + thread + parent.sp + ~ + cm + read.sp + write.sp + *engagement:tp + `@uvH`pubkey + *signature:tp + ~ + == + post +:: new! using wispem's lib +++ tokenise +|= t=@t ^- (each content-list:tp @t) + =/ parsed (rush t markdown:de:md:mdlib) + ?~ parsed [%| 'parsing error'] + :- %& + %+ turn u.parsed de-node +++ de-node |= =node:markdown:md ^- block:tp + ?~ node [%paragraph ~] + ?- -.node + %leaf (de-leaf +.node) + %container (de-cont +.node) + == + +++ de-leaf |= =node:leaf:markdown:md ^- block:tp + ?~ node [%paragraph ~] + ?- -.node + %heading (de-heading node) + %break [%paragraph :~([%break ~])] + %indent-codeblock [%codeblock text.node ''] + %fenced-codeblock [%codeblock text.node info-string.node] + %html [%codeblock text.node 'html'] + %link-ref-definition [%paragraph :~([%link '' label.node])] + %paragraph [%paragraph (de-inline contents.node)] + %blank-line [%paragraph :~([%break ~])] + %table [%paragraph :~([%break ~])] :: TODO + == +++ de-heading |= h=heading:leaf:markdown:md + :+ %heading (flatten-inline contents.h) + ?: .=(1 level.h) %h1 + ?: .=(2 level.h) %h2 + ?: .=(3 level.h) %h3 + ?: .=(4 level.h) %h4 + ?: .=(5 level.h) %h5 %h6 +++ de-inline |= inls=contents:inline:md + =| res=(list inline:tp) + |- ?~ inls (flop res) + =/ inl i.inls + =/ r=inline:tp ?- -.inl + %escape [%codespan char.inl] + %entity [%codespan code.inl] + %code-span [%codespan text.inl] + %line-break [%break ~] + %soft-line-break [%break ~] + %text [%text text.inl] + %emphasis (de-strong +.inl) + %strong (de-strong +.inl) + %link [%link (de-target target.inl) (flatten-inline contents.inl)] + %image [%link (de-target target.inl) (de-target target.inl)] + :: %image [%img (de-target target.inl) alt-text.inl] + %autolink [%text ''] + %html [%codespan text.inl] + == + $(inls t.inls, res [r res]) +++ de-strong |= [char=@t inls=contents:inline:md] +?: .=('_' char) [%italic (flatten-inline inls)] + [%bold (flatten-inline inls)] +++ de-target |= tar=target:ln:md +:: TODO lotsa stuff here + ?- -.tar + %direct text.url.urlt.tar + %ref label.tar + == +++ flatten-inline |= inls=contents:inline:md ^- @t + =/ res "" + |- ?~ inls (crip res) + =/ inl i.inls + =/ r ?+ -.inl "" + %escape (trip char.inl) + %entity (trip code.inl) + %code-span (trip text.inl) + %text (trip text.inl) + %emphasis (trip (flatten-inline contents.inl)) + %strong (trip (flatten-inline contents.inl)) + %link (trip (flatten-inline contents.inl)) + %image (trip (de-target target.inl)) + %html (trip text.inl) + == + $(inls t.inls, res "{res} {r}") +++ de-cont |= =node:container:markdown:md ^- block:tp + ?~ node [%paragraph ~] + ?- -.node + %block-quote [%blockquote (denest +.node)] + %ol [%list (de-list contents.node) .y] + %ul [%list (de-list contents.node) .n] + %tl [%paragraph ~] + == +++ de-list |= lmd=(list markdown:md) ^- (list inline:tp) +:: TODO +~ + :: =| res=(list li:tp) + :: |- ?~ lmd (flop res) + :: =/ nodelist i.lmd + :: =/ blocks=(list block:tp) + :: %+ turn nodelist de-node + :: $(lmd t.lmd, res [blocks res]) + +++ denest |= mde=markdown:md ^- paragraph:tp + =| res=paragraph:tp + |- ?~ mde (flop res) + =/ block (de-node i.mde) + =/ r=paragraph:tp (break-block block) + =/ nr (weld res r) + $(mde t.mde, res nr) + +++ break-block |= =block:tp ^- paragraph:tp +?+ -.block ~ + %paragraph p.block + %blockquote p.block + %heading :~([%text p.block]) + %codeblock :~([%text code.block]) + %eval :~([%text hoon.block]) + :: %list (break-list p.block) +== +++ break-list |= lis=(list li:tp) ^- paragraph:tp + =| res=paragraph:tp + |- ?~ lis (flop res) + =/ par (ibreak-list i.lis) + =/ nr (weld res par) + $(lis t.lis, res nr) +++ ibreak-list |= blocks=(list block:tp) ^- paragraph:tp + =| res=paragraph:tp + |- ?~ blocks (flop res) + =/ par (break-block i.blocks) + =/ nr (weld res par) + $(blocks t.blocks, res nr) + +:: tape -> post:trill, parsing user input from Sail ++$ heading $?(%h1 %h2 %h3 %h4 %h5 %h6) + +++ parse :: Markdown parser. Actually udon parser but it'll do + |= s=tape ^- (unit marl:hoot) :: finally + :: Annoying it requires a line break but then parses it as a space wtf + =, vast + (rust s cram:(sail .y)) +++ tokenize +|= s=@t ^- content-list:tp + =/ t (weld (trip s) "\0a") + =/ parsed (parse t) + :: =/ parsed2 (parse:md t) + :: ~& > diary-parser=parsed2 + :: \0a can't be followed by a space. ever. those are the rules + ?~ parsed ~& error-parsing-markdown=t ~ + (marl-to-cl u.parsed) +++ marl-to-cl +|= =marl:hoot ^- content-list:tp + %- flop + %+ roll marl + |= [=tuna:hoot acc=content-list:tp] + :: man this is an annoying type if I ever saw one + ?@ -.tuna acc + =/ blk (manx-to-block tuna) + ?~ blk acc :_ acc u.blk +++ manx-to-block + |= =manx:hoot ^- (unit block:tp) + ?+ n.g.manx ~ + :: TODO + :: heading %- some [%heading (phead n.g.manx c.manx)] + %p %- some [%paragraph (inline-list c.manx)] + %blockquote %- some [%blockquote (inline-list c.manx)] + %pre %- some [%codeblock (pre c.manx)] + %hr %- some [%paragraph ~[[%break ~]]] + %ul %- some [%list (inline-list c.manx) .n] + %ol %- some [%list (inline-list c.manx) .y] + :: %table %- some (table-rows c.manx) + == +:: ++ list-items +:: |= =marl:hoot ^- (list li:tp) +:: %- flop +:: %+ roll marl |= [=tuna:hoot acc=(list li:tp)] +:: ?@ -.tuna acc +:: ?. ?=(%li n.g.tuna) acc :_ acc (marl-to-cl c.tuna) +:: ++ phead +:: |= [h=heading c=marl:hoot] ^- [p=cord q=heading] +:: :- (get-tag-text c) h +++ inline-list + |= c=marl:hoot ^- (list inline:tp) + %- flop + %+ roll c + |= [=tuna:hoot acc=(list inline:tp)] + ?@ -.tuna acc :_ acc (inline tuna) + ++ inline + |= =manx:hoot ^- inline:tp + ?: ?=(%$ n.g.manx) [%text (get-attrs-text a.g.manx)] + =/ text=@t (get-tag-text c.manx) + ?+ n.g.manx [%text text] + %i [%italic text] + %b [%bold text] + %code [%codespan text] + %br [%break ~] + %a :+ %link (get-attrs-text a.g.manx) (get-tag-text c.manx) + %img :+ %link (get-attr-text a.g.manx %src) (get-attr-text a.g.manx %alt) + == +:: +++ reduce-block +|= c=marl:hoot ^- @t + %+ roll c + |= [=tuna:hoot acc=@t] + ?@ -.tuna acc + ?+ n.g.tuna acc + %p (get-tag-text c.tuna) + == +++ get-attr-text +|= [a=mart:hoot attr=@tas] ^- @t + %- crip %- flop + %+ roll a + |= [[n=mane v=(list beer:hoot)] acc=tape] + ?. .=(attr n) acc + %+ roll v + |= [b=beer:hoot acc=tape] + ?^ b acc [b acc] +++ get-attrs-text :: this assumes we don't care about which attr, which we usually don't +|= a=mart:hoot ^- @t + :: ?: (gte (lent a) 1) + %- crip %- flop + %+ roll a + |= [[n=mane v=(list beer:hoot)] acc=tape] + %+ roll v + |= [b=beer:hoot acc=tape] + ?^ b acc [b acc] +++ get-tag-text +|= c=marl:hoot ^- @t +:: there's only really one child in these things + %+ roll c + |= [=tuna:hoot acc=@t] + ?@ -.tuna acc + %- crip + %- flop + %+ roll a.g.tuna + |= [[n=mane v=(list beer:hoot)] acc=tape] + %+ roll v + |= [b=beer:hoot acc=tape] + ?^ b acc [b acc] + +++ pre + |= c=marl:hoot ^- [cord cord] + :_ '' :: lang not supported, duh + %+ roll c + |= [=tuna:hoot acc=@t] + ?@ -.tuna acc + (get-attrs-text a.g.tuna) + +++ parse-tags +|= t=@t ^- (unit (set @t)) + =/ lst (rush t (csplit:sr com)) + ?~ lst ~ (some (sy u.lst)) +:: post:trill -> (markdown) tape for display on sail +++ block-to-md +|= b=block:tp ^- tape + ?+ -.b "" +%paragraph + %^ foldi:sr p.b "" |= [in=@ud i=inline:tp acc=tape] + =/ il (inline-to-tape i) + ?: .=(+(in) (lent p.b)) + "{acc}{il}" + "{acc}{il} " +%blockquote + %+ weld "> " + %^ foldi:sr p.b "" |= [in=@ud i=inline:tp acc=tape] + =/ il (inline-to-tape i) + ?: .=(+(in) (lent p.b)) + "{acc}{il}" + "{acc}{il} " +%list + %^ foldi:sr p.b "" |= [in=@ud i=inline:tp acc=tape] + =/ li-tape (inline-to-tape i) + =/ line ?: ordered.b + "{<+(in)>}. {li-tape}" + "- {li-tape}" + ?: .=(+(in) (lent p.b)) + "{acc}{line}" + "{acc}{line}\0a" +%media + ?+ -.media.b "})" + :: TODO +%images + :: %^ foldi:sr p.media.b "" |= [i=@ud [url=@t caption=@t] acc=tape] + :: =/ line "})" + :: ?: .=(+(i) (lent p.media.b)) + :: "{acc}{line}" + :: "{acc}{line}\0a" + "" + == +%codeblock + """ + ``` + {(trip code.b)} + ``` + """ +%heading =/ dashes=tape ?- q.b + %h1 "# " + %h2 "## " + %h3 "### " + %h4 "#### " + %h5 "##### " + %h6 "###### " + == "{dashes}{(trip p.b)}" +:: %tasklist "" ::TODO + :: + :: %table acc + :: %eval acc + :: %ref acc + :: %json acc + == +++ latest-post-content +|= cm=content-map:tp ^- content-list:tp + =/ last (pry:corm:tp cm) + ?~ last ~ + +.u.last + +++ content-list-to-md +|= =content-list:tp ^- tape + %^ foldi:sr content-list "" |= [i=@ud b=block:tp acc=tape] + =/ block-tape (block-to-md b) + ?: .=(+(i) (lent content-list)) + "{acc}{block-tape}" + "{acc}{block-tape}\0a\0a" +++ inline-to-tape +|= i=inline:tp ^- tape + ?+ -.i "" + %text (trip p.i) + %italic "_{(trip p.i)}_" + %bold "*{(trip p.i)}*" + %strike "~~{(trip p.i)}~~" + %ship (scow %p p.i) + %codespan "`{(trip p.i)}`" + %link "[{(trip show.i)}]({(trip href.i)})" + :: %img "})" + %break "\0a" + == +++ tags-to-tape +|= t=(set @t) ^- tape + %^ foldi:sr ~(tap in t) "" |= [i=@ud c=@t acc=tape] + ?: .=(+(i) ~(wyt in t)) + "{acc}{(trip c)}" + "{acc}{(trip c)}," + +++ init-content-map |= [cl=content-list:tp date=@da] ^- content-map:tp + (put:corm:tp *content-map:tp date cl) + +-- |
