aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/asbestos/html.templ114
-rw-r--r--cmd/asbestos/html_templ.go403
-rw-r--r--cmd/asbestos/main.go100
-rw-r--r--cmd/mastodon2atproto/main.go245
-rw-r--r--cmd/stickers/data/error.avifbin0 -> 6509 bytes
-rw-r--r--cmd/stickers/data/error.jxlbin0 -> 15104 bytes
-rw-r--r--cmd/stickers/data/error.pngbin0 -> 30864 bytes
-rw-r--r--cmd/stickers/data/error.webpbin0 -> 10548 bytes
-rw-r--r--cmd/stickers/data/not_found.avifbin0 -> 6225 bytes
-rw-r--r--cmd/stickers/data/not_found.jxlbin0 -> 14346 bytes
-rw-r--r--cmd/stickers/data/not_found.pngbin0 -> 29457 bytes
-rw-r--r--cmd/stickers/data/not_found.webpbin0 -> 9824 bytes
-rw-r--r--cmd/stickers/main.go160
-rw-r--r--cmd/stickers/main.templ52
-rw-r--r--cmd/stickers/main_templ.go168
15 files changed, 1242 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)
+}
diff --git a/cmd/mastodon2atproto/main.go b/cmd/mastodon2atproto/main.go
new file mode 100644
index 0000000..a8957a8
--- /dev/null
+++ b/cmd/mastodon2atproto/main.go
@@ -0,0 +1,245 @@
+package main
+
+import (
+ "context"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "image"
+ "image/jpeg"
+ _ "image/png"
+ "log"
+ "log/slog"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/bluesky-social/indigo/api/atproto"
+ lexutil "github.com/bluesky-social/indigo/lex/util"
+ "github.com/rivo/uniseg"
+ "within.website/x/internal"
+ "within.website/x/web/bskybot"
+ "within.website/x/web/mastosan"
+)
+
+var (
+ bskyAuthkey = flag.String("bsky-authkey", "", "Bluesky authkey")
+ bskyHandle = flag.String("bsky-handle", "", "Bluesky handle/email")
+ bskyPDS = flag.String("bsky-pds", "https://bsky.social", "Bluesky PDS")
+
+ afterStr = flag.String("after", "2017-04-22T04:59:14Z", "only consider posts after this point")
+)
+
+func main() {
+ internal.HandleStartup()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ agent := bskybot.NewAgent(ctx, *bskyPDS, *bskyHandle, *bskyAuthkey)
+ if err := agent.Connect(ctx); err != nil {
+ log.Fatal(err)
+ }
+
+ if flag.NArg() != 1 {
+ fmt.Println("Usage: mastodon2atproto [flags] <data dir>")
+ }
+
+ dir := flag.Arg(0)
+
+ fin, err := os.Open(filepath.Join(dir, "outbox.json"))
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer fin.Close()
+
+ after, err := time.Parse(time.RFC3339, *afterStr)
+ if err != nil {
+ log.Fatalf("can't parse after time: %v", err)
+ }
+
+ var oc OrderedCollection
+ if err := json.NewDecoder(fin).Decode(&oc); err != nil {
+ log.Fatal(err)
+ }
+
+ slog.Info("found items", "count", oc.TotalItems)
+
+ var out []Object
+
+ for _, item := range oc.OrderedItems {
+ slog.Debug("found item", "type", item.Type)
+
+ if item.Type == "Announce" {
+ continue
+ }
+
+ var obj Object
+ if err := json.Unmarshal(item.Object, &obj); err != nil {
+ log.Fatal(err)
+ }
+
+ if obj.InReplyTo != nil {
+ continue
+ }
+
+ text, err := mastosan.Text(ctx, obj.Content)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if strings.HasPrefix(text, "@") {
+ continue
+ }
+
+ if uniseg.GraphemeClusterCount(text) > 300 {
+ continue
+ }
+
+ if obj.Published.Before(after) {
+ continue
+ }
+
+ skip := false
+ for _, att := range obj.Attachment {
+ if !strings.HasPrefix(att.URL, "image/") {
+ skip = true
+ }
+ }
+
+ if skip {
+ continue
+ }
+
+ obj.Content = text
+
+ slog.Debug("found post", "text", text, "published", obj.Published)
+
+ out = append(out, obj)
+ }
+
+ slog.Info("found candidate posts for migration", "len", len(out))
+
+ t := time.NewTicker(5 * time.Second)
+ defer t.Stop()
+
+ for _, obj := range out {
+ <-t.C
+
+ slog.Info("migrating post", "post", obj)
+
+ pb := bskybot.NewPostBuilder(obj.Content).
+ AtTime(obj.Published)
+
+ if len(obj.Attachment) != 0 {
+ var blobs []lexutil.LexBlob
+ var images []bskybot.Image
+ for _, att := range obj.Attachment {
+ att.URL = strings.TrimPrefix(att.URL, "/interlinked-mst3k")
+ fname := filepath.Join(dir, att.URL)
+
+ st, err := os.Stat(fname)
+ if err != nil {
+ log.Fatalf("can't stat file: %v", err)
+ }
+ if st.Size() >= 976560 {
+ fname, err = convertToJPG(fname)
+ if err != nil {
+ log.Fatalf("can't convert to jpeg: %v", err)
+ }
+ }
+
+ fin, err := os.Open(fname)
+ if err != nil {
+ log.Fatalf("can't open file: %v", err)
+ }
+
+ resp, err := atproto.RepoUploadBlob(ctx, agent.Client(), fin)
+ if err != nil {
+ log.Fatalf("can't upload blob: %v", err)
+ }
+
+ blobs = append(blobs, lexutil.LexBlob{
+ Ref: resp.Blob.Ref,
+ MimeType: resp.Blob.MimeType,
+ Size: resp.Blob.Size,
+ })
+ images = append(images, bskybot.Image{})
+ }
+
+ pb = pb.WithImages(blobs, images)
+ }
+
+ post, err := pb.Build()
+ if err != nil {
+ log.Fatalf("can't build post: %v", err)
+ }
+
+ cid, uri, err := agent.PostToFeed(ctx, post)
+ if err != nil {
+ log.Fatalf("can't post to feed: %v", err)
+ }
+
+ pathSp := strings.Split(uri, "/")
+ id := pathSp[len(pathSp)-1]
+
+ postURL := fmt.Sprintf("https://bsky.app/profile/%s/post/%s", *bskyHandle, id)
+
+ slog.Info("reposted old post", "at", obj.Published, "cid", cid, "uri", uri, "url", postURL)
+ }
+}
+
+type OrderedCollection struct {
+ TotalItems int `json:"totalItems"`
+ OrderedItems []Item `json:"orderedItems"`
+}
+
+type Item struct {
+ Type string `json:"type"`
+ Object json.RawMessage `json:"object"`
+}
+
+type Object struct {
+ ID string `json:"id"`
+ To []string `json:"to"`
+ CC []string `json:"cc"`
+ InReplyTo *string `json:"inReplyTo"`
+ Published time.Time `json:"published"`
+ Content string `json:"content"`
+ Attachment []Attachment `json:"attachment"`
+ DirectMessage bool `json:"directMessage"`
+}
+
+type Attachment struct {
+ MediaType string `json:"mediaType"`
+ URL string `json:"url"`
+ Name string `json:"name"`
+}
+
+func convertToJPG(fname string) (string, error) {
+ fin, err := os.Open(fname)
+ if err != nil {
+ return "", fmt.Errorf("failed to open %s: %w", fname, err)
+ }
+ defer fin.Close()
+
+ img, _, err := image.Decode(fin)
+ if err != nil {
+ return "", fmt.Errorf("failed to decode PNG file: %w", err)
+ }
+
+ outFileName := fname[:len(fname)-len(filepath.Ext(fname))] + ".jpeg"
+ outFile, err := os.Create(outFileName)
+ if err != nil {
+ return "", fmt.Errorf("failed to create JPEG file: %w", err)
+ }
+ defer outFile.Close()
+
+ options := jpeg.Options{Quality: 85}
+ if err := jpeg.Encode(outFile, img, &options); err != nil {
+ return "", fmt.Errorf("failed to encode JPEG file: %w", err)
+ }
+
+ return outFileName, nil
+}
diff --git a/cmd/stickers/data/error.avif b/cmd/stickers/data/error.avif
new file mode 100644
index 0000000..505da03
--- /dev/null
+++ b/cmd/stickers/data/error.avif
Binary files differ
diff --git a/cmd/stickers/data/error.jxl b/cmd/stickers/data/error.jxl
new file mode 100644
index 0000000..cb6cf89
--- /dev/null
+++ b/cmd/stickers/data/error.jxl
Binary files differ
diff --git a/cmd/stickers/data/error.png b/cmd/stickers/data/error.png
new file mode 100644
index 0000000..3143cdf
--- /dev/null
+++ b/cmd/stickers/data/error.png
Binary files differ
diff --git a/cmd/stickers/data/error.webp b/cmd/stickers/data/error.webp
new file mode 100644
index 0000000..ebd4604
--- /dev/null
+++ b/cmd/stickers/data/error.webp
Binary files differ
diff --git a/cmd/stickers/data/not_found.avif b/cmd/stickers/data/not_found.avif
new file mode 100644
index 0000000..fa2e6de
--- /dev/null
+++ b/cmd/stickers/data/not_found.avif
Binary files differ
diff --git a/cmd/stickers/data/not_found.jxl b/cmd/stickers/data/not_found.jxl
new file mode 100644
index 0000000..f7cc7df
--- /dev/null
+++ b/cmd/stickers/data/not_found.jxl
Binary files differ
diff --git a/cmd/stickers/data/not_found.png b/cmd/stickers/data/not_found.png
new file mode 100644
index 0000000..043e0d0
--- /dev/null
+++ b/cmd/stickers/data/not_found.png
Binary files differ
diff --git a/cmd/stickers/data/not_found.webp b/cmd/stickers/data/not_found.webp
new file mode 100644
index 0000000..42188fb
--- /dev/null
+++ b/cmd/stickers/data/not_found.webp
Binary files differ
diff --git a/cmd/stickers/main.go b/cmd/stickers/main.go
new file mode 100644
index 0000000..67f1e83
--- /dev/null
+++ b/cmd/stickers/main.go
@@ -0,0 +1,160 @@
+package main
+
+import (
+ "context"
+ "embed"
+ "flag"
+ "fmt"
+ "log"
+ "log/slog"
+ "net/http"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/a-h/templ"
+ "github.com/aws/aws-sdk-go-v2/aws"
+ v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
+ awsConfig "github.com/aws/aws-sdk-go-v2/config"
+ "github.com/aws/aws-sdk-go-v2/service/s3"
+ "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", ":3923", "TCP address to bind to")
+ bucketName = flag.String("bucket-name", "xedn", "Bucket to pull from")
+ folderName = flag.String("folder-name", "stickers", "Folder name for stickers")
+
+ //go:embed data/*
+ static embed.FS
+
+ cache = map[string]struct{}{}
+ cacheLock = sync.RWMutex{}
+)
+
+func main() {
+ internal.HandleStartup()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ cfg, err := awsConfig.LoadDefaultConfig(ctx)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ s3c := s3.NewFromConfig(cfg, func(o *s3.Options) {
+ o.UsePathStyle = true
+ })
+
+ presigner := Presigner{s3.NewPresignClient(s3c)}
+ _ = presigner
+
+ mux := http.NewServeMux()
+ htmx.Mount(mux)
+ xess.Mount(mux)
+
+ mux.HandleFunc("GET /{$}", func(w http.ResponseWriter, r *http.Request) {
+ character := r.FormValue("character")
+ mood := r.FormValue("mood")
+
+ templ.Handler(
+ xess.Simple("Sticker Tester", index(character, mood)),
+ ).ServeHTTP(w, r)
+ })
+
+ mux.HandleFunc("GET /sticker/{name}/{mood}", func(w http.ResponseWriter, r *http.R