Lasa is a stateless proxy that generates a RSS or an Atom feed from a Standard.site publication. lasa.anhgelus.world
rss atom atprotocol standard-site atproto
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(cli): legal notice

+33 -17
+1 -1
atom.go
··· 26 26 return err 27 27 } 28 28 return template.Must(template.New("rss").Funcs(map[string]any{ 29 - "isSet": isSet, 29 + "isSet": IsSet, 30 30 }).ParseFS(atomTemplate, "atom.xml")).ExecuteTemplate(w, "atom.xml", data) 31 31 }
+12
cmd/lasad/author.html
··· 62 62 border-bottom: 2px solid #000; 63 63 margin: 0; 64 64 } 65 + footer { 66 + display: flex; 67 + flex-direction: row; 68 + gap: 1rem; 69 + padding: 1rem; 70 + } 65 71 66 72 @media only screen and (prefers-color-scheme: dark) { 67 73 :root { ··· 103 109 </div> 104 110 {{ end -}} 105 111 </main> 112 + <footer> 113 + <a href="https://tangled.org/anhgelus.world/lasa/" target="_blank">Source code</a> 114 + {{ if isSet .LegalNotice }} 115 + <a href="{{ .LegalNotice }}">Legal notice</a> 116 + {{ end }} 117 + </footer> 106 118 </body> 107 119 </html>
+10 -9
cmd/lasad/config/config.go
··· 13 13 const DefaultPath = "/etc/lasad.toml" 14 14 15 15 type Config struct { 16 - Domain string `toml:"domain"` 17 - Port uint `toml:"port"` 18 - Cache *Cache `toml:"cache"` 16 + Domain string `toml:"domain"` 17 + Port uint `toml:"port"` 18 + Cache *Cache `toml:"cache"` 19 + LegalNotice *string `toml:"legal_notice_url"` 19 20 } 20 21 21 22 type Cache struct { 22 - Host string `toml:"host"` 23 - Port uint `toml:"port"` 24 - DB uint `toml:"db"` 25 - Duration uint `toml:"duration"` 26 - Auth CacheAuth `toml:"auth"` 23 + Host string `toml:"host"` 24 + Port uint `toml:"port"` 25 + DB uint `toml:"db"` 26 + Duration uint `toml:"duration"` 27 + Auth *CacheAuth `toml:"auth"` 27 28 } 28 29 29 30 type CacheAuth struct { ··· 35 36 func (c *Cache) Connect() (*glide.Client, error) { 36 37 cfg := config.NewClientConfiguration(). 37 38 WithAddress(&config.NodeAddress{Host: c.Host, Port: int(c.Port)}) 38 - if c.Auth.Password != "" { 39 + if c.Auth != nil { 39 40 if c.Auth.Username != "" { 40 41 cfg = cfg.WithCredentials(config.NewServerCredentials(c.Auth.Username, c.Auth.Password)) 41 42 } else {
+1
cmd/lasad/default.toml
··· 1 1 domain = "example.org" 2 2 port = 8000 3 + #legal_notice_url = "https://example.org/legal" 3 4 4 5 # if you are using valkey 5 6 #[cache]
+7 -2
cmd/lasad/directory.go
··· 14 14 glide "github.com/valkey-io/valkey-glide/go/v2" 15 15 site "tangled.org/anhgelus.world/goat-site" 16 16 "tangled.org/anhgelus.world/lasa" 17 + "tangled.org/anhgelus.world/lasa/cmd/lasad/config" 17 18 "tangled.org/anhgelus.world/xrpc" 18 19 "tangled.org/anhgelus.world/xrpc/atproto" 19 20 ) ··· 73 74 if err != nil { 74 75 return nil, err 75 76 } 77 + cfg := ctx.Value(keyCfg).(*config.Config) 76 78 h, _ := doc.Handle() 77 79 v := struct { 78 80 Author string 81 + LegalNotice *string 79 82 Publications []Publication 80 - }{Author: h.String()} 83 + }{Author: h.String(), LegalNotice: cfg.LegalNotice} 81 84 pubs, _, err := xrpc.ListRecords[*site.Publication](ctx, client, did, 0, "", false) 82 85 if err != nil { 83 86 return nil, err ··· 93 96 v.Publications[i] = Publication{pub.Value.URL.String(), link, pub.Value.Name, uri.RecordKey().String()} 94 97 } 95 98 var bf bytes.Buffer 96 - err = template.Must(template.ParseFS(files, "author.html")).ExecuteTemplate(&bf, "author.html", v) 99 + err = template.Must(template.New("").Funcs(map[string]any{ 100 + "isSet": lasa.IsSet, 101 + }).ParseFS(files, "author.html")).ExecuteTemplate(&bf, "author.html", v) 97 102 if err != nil { 98 103 return nil, err 99 104 }
-3
cmd/lasad/index.html
··· 97 97 Lasa is open-source: check out the <a href="https://tangled.org/anhgelus.world/lasa" target="_blank">source 98 98 code</a> hosted on Tangled, an ATProto forge. 99 99 </p> 100 - <p> 101 - Lasa is a project by <a href="https://anhgelus.world/" target="_blank">Anhgelus Morhtuuzh</a>. 102 - </p> 103 100 </body> 104 101 </html>
+2 -2
rss.go
··· 61 61 return err 62 62 } 63 63 return template.Must(template.New("rss").Funcs(map[string]any{ 64 - "isSet": isSet, 64 + "isSet": IsSet, 65 65 }).ParseFS(rssTemplate, "rss.xml")).ExecuteTemplate(w, "rss.xml", data) 66 66 } 67 67 ··· 125 125 return data, nil 126 126 } 127 127 128 - func isSet(v any) bool { 128 + func IsSet(v any) bool { 129 129 return !reflect.ValueOf(v).IsZero() 130 130 }