diff options
| author | Xe Iaso <me@xeiaso.net> | 2025-01-11 15:14:44 -0500 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2025-01-11 15:14:44 -0500 |
| commit | 231202b2d3bfdda154b68983f6f712bfc1f50b3a (patch) | |
| tree | b47d51735eeff35bab9945fb4067397afe5918a4 /cmd/asbestos | |
| parent | 174c080d1d65701e02cdb3249ef6d36139d9c2e8 (diff) | |
| download | x-231202b2d3bfdda154b68983f6f712bfc1f50b3a.tar.xz x-231202b2d3bfdda154b68983f6f712bfc1f50b3a.zip | |
cmd: add stickers
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/asbestos')
| -rw-r--r-- | cmd/asbestos/html.templ | 114 | ||||
| -rw-r--r-- | cmd/asbestos/html_templ.go | 403 | ||||
| -rw-r--r-- | cmd/asbestos/main.go | 100 |
3 files changed, 617 insertions, 0 deletions
diff --git a/cmd/asbestos/html.templ b/cmd/asbestos/html.templ new file mode 100644 index 0000000..ae57782 --- /dev/null +++ b/cmd/asbestos/html.templ @@ -0,0 +1,114 @@ +package main + +import ( + "within.website/x/htmx" + "within.website/x/xess" +) + +templ NotFound() { + <p>The URL you requested could not be found. Please check your URL and hang up to try your call again.</p> +} + +templ allClear() { + <p>Your data was not found in the dataset. No action is required on your part.</p> +} + +templ Error(why string) { + <p>Oopsie whoopsie uwu we made a fucky-wucky! A widdle fucko boingo! The code monkeys at our headquarters are working VEWY HARD to fix this!</p> + <p>Reason: { why }</p> +} + +templ Index() { + <p>TODO placeholder</p> + <input + style="display: block" + class="form-control" + type="search" + name="search" + placeholder="Begin Typing To Search Users..." + hx-post="/search" + hx-trigger="input changed delay:500ms, search" + hx-target="#search-results" + hx-indicator=".htmx-indicator" + hx-swap="innerHTML" + /> + <br/> + <div id="search-results"></div> +} + +templ headArea() { + @htmx.Use() + <style> + .no-copy { + -webkit-user-select: none; /* Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently supported by Chrome, Opera and Edge */ + } + </style> +} + +templ footer() { + <p> + A product of <a href="https://techaro.lol">Techaro</a> + <a href="https://bsky.app/profile/techaro.lol"> + { "@techaro.lol" } + </a>, the only ethical AI company + </p> +} + +templ Layout(title string, body templ.Component) { + @xess.Base( + title, + headArea(), + nil, + body, + footer(), + ) +} + +templ searchPage(authorDID string, posts []Post) { + <table> + <thead> + <tr> + <th>Created at</th> + <th>Text</th> + <th>Link</th> + </tr> + </thead> + <tbody> + for _, post := range posts { + <tr> + <td>{ post.CreatedAt }</td> + <td>{ post.Text }</td> + <td><a href={ templ.SafeURL(post.BlueskyURL) }>🔗</a></td> + </tr> + } + </tbody> + </table> + <div id="dmca-notice"> + <p>Since your data is in this dataset, here's what you can do about it:</p> + <p>Compose an email to <code>dmca@huggingface.co</code> with the subject line <code>DMCA Takedown Request</code> and something like the following body (rephrase this in your own words):</p> + <blockquote class="no-copy"> + Hello, + <br/> + <br/> + I am writing to you to inform you that my data is present in the dataset <a href="https://huggingface.co/datasets/bluesky-community/one-million-bluesky-posts">bluesky-community/one-million-bluesky-posts</a> and I did not consent to it being included. I would like to request that you remove my data from the dataset. + <br/> + <br/> + You can identify my data by searching for the following DID in the <code>author_did</code> column: <code>{ authorDID }</code> + <br/> + <br/> + Thank you for your attention and patience in this matter. + <br/> + <br/> + Sincerely, + <br/> + <br/> + { "(Your Name here)" }, { "(Your Email here)" } + <br/> + { "(identified as" } { authorDID }{ ")" } + </blockquote> + <p>For more information, please refer to the <a href="https://huggingface.co/datasets/bluesky-community/one-million-bluesky-posts/discussions/12">dataset page</a>.</p> + </div> +} diff --git a/cmd/asbestos/html_templ.go b/cmd/asbestos/html_templ.go new file mode 100644 index 0000000..7ac5c03 --- /dev/null +++ b/cmd/asbestos/html_templ.go @@ -0,0 +1,403 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package main + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "within.website/x/htmx" + "within.website/x/xess" +) + +func NotFound() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p>The URL you requested could not be found. Please check your URL and hang up to try your call again.</p>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func allClear() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p>Your data was not found in the dataset. No action is required on your part.</p>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func Error(why string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p>Oopsie whoopsie uwu we made a fucky-wucky! A widdle fucko boingo! The code monkeys at our headquarters are working VEWY HARD to fix this!</p><p>Reason: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(why) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 18, Col: 17} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func Index() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p>TODO placeholder</p><input style=\"display: block\" class=\"form-control\" type=\"search\" name=\"search\" placeholder=\"Begin Typing To Search Users...\" hx-post=\"/search\" hx-trigger=\"input changed delay:500ms, search\" hx-target=\"#search-results\" hx-indicator=\".htmx-indicator\" hx-swap=\"innerHTML\"><br><div id=\"search-results\"></div>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func headArea() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = htmx.Use().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<style>\n .no-copy {\n -webkit-user-select: none; /* Safari */\n -moz-user-select: none; /* Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* Non-prefixed version, currently supported by Chrome, Opera and Edge */\n }\n </style>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func footer() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p>A product of <a href=\"https://techaro.lol\">Techaro</a> <a href=\"https://bsky.app/profile/techaro.lol\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs("@techaro.lol") + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 55, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>, the only ethical AI company</p>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func Layout(title string, body templ.Component) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = xess.Base( + title, + headArea(), + nil, + body, + footer(), + ).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func searchPage(authorDID string, posts []Post) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<table><thead><tr><th>Created at</th><th>Text</th><th>Link</th></tr></thead> <tbody>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, post := range posts { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><td>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(post.CreatedAt) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 82, Col: 25} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(post.Text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 83, Col: 20} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td><a href=\"") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 templ.SafeURL = templ.SafeURL(post.BlueskyURL) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var13))) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">🔗</a></td></tr>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody></table><div id=\"dmca-notice\"><p>Since your data is in this dataset, here's what you can do about it:</p><p>Compose an email to <code>dmca@huggingface.co</code> with the subject line <code>DMCA Takedown Request</code> and something like the following body (rephrase this in your own words):</p><blockquote class=\"no-copy\">Hello,<br><br>I am writing to you to inform you that my data is present in the dataset <a href=\"https://huggingface.co/datasets/bluesky-community/one-million-bluesky-posts\">bluesky-community/one-million-bluesky-posts</a> and I did not consent to it being included. I would like to request that you remove my data from the dataset.<br><br>You can identify my data by searching for the following DID in the <code>author_did</code> column: <code>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(authorDID) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 99, Col: 119} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</code><br><br>Thank you for your attention and patience in this matter.<br><br>Sincerely,<br><br>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs("(Your Name here)") + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 108, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(", ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs("(Your Email here)") + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 108, Col: 48} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<br>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs("(identified as") + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 110, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(authorDID) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 110, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(")") + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html.templ`, Line: 110, Col: 42} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</blockquote><p>For more information, please refer to the <a href=\"https://huggingface.co/datasets/bluesky-community/one-million-bluesky-posts/discussions/12\">dataset page</a>.</p></div>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/cmd/asbestos/main.go b/cmd/asbestos/main.go new file mode 100644 index 0000000..9ab1f8e --- /dev/null +++ b/cmd/asbestos/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "database/sql" + "flag" + "fmt" + "log" + "log/slog" + "net/http" + + "github.com/a-h/templ" + _ "github.com/mattn/go-sqlite3" + "within.website/x/htmx" + "within.website/x/internal" + "within.website/x/xess" +) + +//go:generate go run github.com/a-h/templ/cmd/templ@latest generate + +var ( + bind = flag.String("bind", ":8069", "http port to bind on") + dbURL = flag.String("database-url", "", "path to sqlite database") +) + +func main() { + internal.HandleStartup() + + slog.Info("opening database", "database_url", *dbURL) + db, err := sql.Open("sqlite3", *dbURL) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + s := &Server{db: db} + + mux := http.NewServeMux() + xess.Mount(mux) + htmx.Mount(mux) + + mux.Handle("/{$}", templ.Handler( + Layout("Asbestos", Index()), + )) + + mux.HandleFunc("POST /search", s.searchHTMXPage) + + fmt.Printf("http://localhost%s\n", *bind) + log.Fatal(http.ListenAndServe(*bind, mux)) +} + +type Server struct { + db *sql.DB +} + +type Post struct { + ID int + Text string + CreatedAt string + Author string + URI string + HasImages bool + ReplyTo sql.NullString + BlueskyURL string +} + +func (s *Server) getPostsByAuthor(author string) ([]Post, error) { + rows, err := s.db.Query("SELECT id, text, created_at, author, uri, has_images, reply_to, bluesky_url FROM posts WHERE author = ?", author) + if err != nil { + return nil, err + } + defer rows.Close() + + var posts []Post + for rows.Next() { + var post Post + if err := rows.Scan(&post.ID, &post.Text, &post.CreatedAt, &post.Author, &post.URI, &post.HasImages, &post.ReplyTo, &post.BlueskyURL); err != nil { + return nil, err + } + posts = append(posts, post) + } + return posts, nil +} + +func (s *Server) searchHTMXPage(w http.ResponseWriter, r *http.Request) { + query := r.FormValue("search") + + posts, err := s.getPostsByAuthor(query) + if err != nil { + slog.Error("can't find posts", "author", query, "err", err) + templ.Handler(Error(err.Error())).ServeHTTP(w, r) + return + } + + if len(posts) == 0 { + templ.Handler(allClear()).ServeHTTP(w, r) + return + } + + templ.Handler(searchPage(query, posts)).ServeHTTPStreamed(w, r) +} |
