diff --git a/cmd/athome/README.md b/cmd/athome/README.md index f4df2480..c22def96 100644 --- a/cmd/athome/README.md +++ b/cmd/athome/README.md @@ -2,71 +2,4 @@ athome: Public Bluesky Web Home =============================== -```text -me: can we have public web interface? -mom: we have public web interface at home -public web interface at home: -``` - -1. run this web service somewhere -2. point one or more handle domains to it (CNAME or reverse proxy) -3. serves up profile and feed for that account only -4. fetches data from public bsky app view API - -⚠️ This is a fun little proof-of-concept ⚠️ - -Not all post features are rendered, has not been hardened against clever Unicode tricks, etc. - - -## Running athome - -The recommended way to run `athome` is behind a `caddy` HTTPS server which does automatic on-demand SSL certificate registration (using Let's Encrypt). - -Build and run `athome`: - - go build ./cmd/athome - - # will listen on :8200 by default - ./athome serve - -Create a `Caddyfile`: - -``` -{ - on_demand_tls { - interval 1h - burst 8 - } -} - -:443 { - reverse_proxy localhost:8200 - tls YOUREMAIL@example.com { - on_demand - } -} -``` - -Run `caddy`: - - caddy run - - -## Configuring a Handle - -The easiest way, if there is no existing web service on the handle domain, is to get the handle resolution working with the DNS TXT record option, then point the domain itself to a `athome` service using an A/AAAA or CNAME record. - -If there is an existing web service (eg, a blog), then handle resolution can be set up using either the DNS TXT mechanism or HTTP `/.well-known/` mechanism. Then HTTP proxy paths starting `/bsky` to an `athome` service. - -Here is an nginx config snippet demonstrating HTTP proxying: - -``` -location /bsky { - // in theory https:// should work, on default port? - proxy_pass http://athome.example.com:8200; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-Proto https; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -} -``` +**NOTE: this proof-of-concept has moved to [cobalt](https://tangled.org/@bnewbold.net/cobalt/tree/main/cmd/athome)** diff --git a/cmd/athome/handlers.go b/cmd/athome/handlers.go deleted file mode 100644 index 229cf1eb..00000000 --- a/cmd/athome/handlers.go +++ /dev/null @@ -1,174 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "strings" - - appbsky "github.com/bluesky-social/indigo/api/bsky" - "github.com/bluesky-social/indigo/atproto/syntax" - - "github.com/flosch/pongo2/v6" - "github.com/labstack/echo/v4" -) - -func (srv *Server) reqHandle(c echo.Context) syntax.Handle { - host := c.Request().Host - host = strings.SplitN(host, ":", 2)[0] - handle, err := syntax.ParseHandle(host) - if err != nil { - slog.Warn("host is not a valid handle, fallback to default", "hostname", host) - handle = srv.defaultHandle - } - return handle -} - -func (srv *Server) WebHome(c echo.Context) error { - return c.Redirect(http.StatusFound, "/bsky") -} - -func (srv *Server) WebRepoCar(c echo.Context) error { - handle := srv.reqHandle(c) - ident, err := srv.dir.LookupHandle(c.Request().Context(), handle) - if err != nil { - return err - } - return c.Redirect(http.StatusFound, ident.PDSEndpoint()+"/xrpc/com.atproto.sync.getRepo?did="+ident.DID.String()) -} - -func (srv *Server) WebPost(c echo.Context) error { - ctx := c.Request().Context() - req := c.Request() - data := pongo2.Context{} - handle := srv.reqHandle(c) - // TODO: parse rkey - rkey := c.Param("rkey") - - // requires two fetches: first fetch profile (!) - pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String()) - if err != nil { - slog.Warn("failed to fetch handle", "handle", handle, "err", err) - // TODO: only if "not found" - return echo.NewHTTPError(404, fmt.Sprintf("handle not found: %s", handle)) - } - did := pv.Did - data["did"] = did - - // then fetch the post thread (with extra context) - aturi := fmt.Sprintf("at://%s/app.bsky.feed.post/%s", did, rkey) - tpv, err := appbsky.FeedGetPostThread(ctx, srv.xrpcc, 8, 8, aturi) - if err != nil { - slog.Warn("failed to fetch post", "aturi", aturi, "err", err) - // TODO: only if "not found" - return echo.NewHTTPError(404, "post not found: %s", handle) - } - data["postView"] = tpv.Thread.FeedDefs_ThreadViewPost - data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path) - return c.Render(http.StatusOK, "post.html", data) -} - -func (srv *Server) WebProfile(c echo.Context) error { - ctx := c.Request().Context() - data := pongo2.Context{} - handle := srv.reqHandle(c) - - pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String()) - if err != nil { - slog.Warn("failed to fetch handle", "handle", handle, "err", err) - // TODO: only if "not found" - return echo.NewHTTPError(404, fmt.Sprintf("handle not found: %s", handle)) - } else { - req := c.Request() - data["profileView"] = pv - data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path) - } - did := pv.Did - data["did"] = did - - af, err := appbsky.FeedGetAuthorFeed(ctx, srv.xrpcc, handle.String(), "", "posts_no_replies", false, 100) - if err != nil { - slog.Warn("failed to fetch author feed", "handle", handle, "err", err) - // TODO: show some error? - } else { - data["authorFeed"] = af.Feed - //slog.Warn("author feed", "feed", af.Feed) - } - - return c.Render(http.StatusOK, "profile.html", data) -} - -// https://medium.com/@etiennerouzeaud/a-rss-feed-valid-in-go-edfc22e410c7 -type Item struct { - Title string `xml:"title"` - Link string `xml:"link"` - Description string `xml:"description"` - PubDate string `xml:"pubDate"` -} - -type rss struct { - Version string `xml:"version,attr"` - Description string `xml:"channel>description"` - Link string `xml:"channel>link"` - Title string `xml:"channel>title"` - - Item []Item `xml:"channel>item"` -} - -func (srv *Server) WebRepoRSS(c echo.Context) error { - ctx := c.Request().Context() - handle := srv.reqHandle(c) - - pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String()) - if err != nil { - slog.Warn("failed to fetch handle", "handle", handle, "err", err) - // TODO: only if "not found" - return echo.NewHTTPError(404, fmt.Sprintf("handle not found: %s", handle)) - //return err - } - - af, err := appbsky.FeedGetAuthorFeed(ctx, srv.xrpcc, handle.String(), "", "posts_no_replies", false, 30) - if err != nil { - slog.Warn("failed to fetch author feed", "handle", handle, "err", err) - return err - } - - posts := []Item{} - for _, p := range af.Feed { - // only include own posts in RSS - if p.Post.Author.Did != pv.Did { - continue - } - aturi, err := syntax.ParseATURI(p.Post.Uri) - if err != nil { - return err - } - rec := p.Post.Record.Val.(*appbsky.FeedPost) - // only top-level posts in RSS - if rec.Reply != nil { - continue - } - posts = append(posts, Item{ - Title: "@" + handle.String() + " post", - Link: fmt.Sprintf("https://%s/bsky/post/%s", handle, aturi.RecordKey().String()), - Description: rec.Text, - PubDate: rec.CreatedAt, - }) - } - - title := "@" + handle.String() - if pv.DisplayName != nil { - title = title + " - " + *pv.DisplayName - } - desc := "" - if pv.Description != nil { - desc = *pv.Description - } - feed := &rss{ - Version: "2.0", - Description: desc, - Link: fmt.Sprintf("https://%s/bsky", handle.String()), - Title: title, - Item: posts, - } - return c.XML(http.StatusOK, feed) -} diff --git a/cmd/athome/main.go b/cmd/athome/main.go deleted file mode 100644 index eb791c98..00000000 --- a/cmd/athome/main.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "fmt" - slogging "log/slog" - "os" - - "github.com/carlmjohnson/versioninfo" - "github.com/urfave/cli/v2" - - _ "github.com/joho/godotenv/autoload" -) - -var ( - slog = slogging.New(slogging.NewJSONHandler(os.Stdout, nil)) - version = versioninfo.Short() -) - -func main() { - if err := run(os.Args); err != nil { - slog.Error("fatal", "err", err) - os.Exit(-1) - } -} - -func run(args []string) error { - - app := cli.App{ - Name: "athome", - Usage: "public web interface to bluesky account content", - } - - app.Commands = []*cli.Command{ - &cli.Command{ - Name: "serve", - Usage: "run the server", - Action: serve, - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "appview-host", - Usage: "method, hostname, and port of AppView instance", - Value: "https://api.bsky.app", - EnvVars: []string{"ATP_APPVIEW_HOST"}, - }, - &cli.StringFlag{ - Name: "bind", - Usage: "Specify the local IP/port to bind to", - Required: false, - Value: ":8200", - EnvVars: []string{"ATHOME_BIND"}, - }, - &cli.BoolFlag{ - Name: "debug", - Usage: "Enable debug mode", - Value: false, - Required: false, - EnvVars: []string{"DEBUG"}, - }, - }, - }, - &cli.Command{ - Name: "version", - Usage: "print version", - Action: func(cctx *cli.Context) error { - fmt.Println(version) - return nil - }, - }, - } - - return app.Run(args) -} diff --git a/cmd/athome/renderer.go b/cmd/athome/renderer.go deleted file mode 100644 index 0fa3cb1c..00000000 --- a/cmd/athome/renderer.go +++ /dev/null @@ -1,85 +0,0 @@ -package main - -import ( - "bytes" - "embed" - "errors" - "fmt" - "io" - "path/filepath" - - "github.com/flosch/pongo2/v6" - "github.com/labstack/echo/v4" -) - -//go:embed templates/* -var TemplateFS embed.FS - -type RendererLoader struct { - prefix string - fs *embed.FS -} - -func NewRendererLoader(prefix string, fs *embed.FS) pongo2.TemplateLoader { - return &RendererLoader{ - prefix: prefix, - fs: fs, - } -} -func (l *RendererLoader) Abs(_, name string) string { - // TODO: remove this workaround - // Figure out why this method is being called - // twice on template names resulting in a failure to resolve - // the template name. - if filepath.HasPrefix(name, l.prefix) { - return name - } - return filepath.Join(l.prefix, name) -} - -func (l *RendererLoader) Get(path string) (io.Reader, error) { - b, err := l.fs.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("reading template %q failed: %w", path, err) - } - return bytes.NewReader(b), nil -} - -type Renderer struct { - TemplateSet *pongo2.TemplateSet - Debug bool -} - -func NewRenderer(prefix string, fs *embed.FS, debug bool) *Renderer { - return &Renderer{ - TemplateSet: pongo2.NewSet(prefix, NewRendererLoader(prefix, fs)), - Debug: debug, - } -} - -func (r Renderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error { - var ctx pongo2.Context - - if data != nil { - var ok bool - ctx, ok = data.(pongo2.Context) - if !ok { - return errors.New("no pongo2.Context data was passed") - } - } - - var t *pongo2.Template - var err error - - if r.Debug { - t, err = pongo2.FromFile(name) - } else { - t, err = r.TemplateSet.FromFile(name) - } - - if err != nil { - return err - } - - return t.ExecuteWriter(ctx, w) -} diff --git a/cmd/athome/service.go b/cmd/athome/service.go deleted file mode 100644 index 739b75eb..00000000 --- a/cmd/athome/service.go +++ /dev/null @@ -1,191 +0,0 @@ -package main - -import ( - "context" - "embed" - "errors" - "io/fs" - "net/http" - "os" - "os/signal" - "syscall" - "time" - - "github.com/bluesky-social/indigo/atproto/identity" - "github.com/bluesky-social/indigo/atproto/syntax" - "github.com/bluesky-social/indigo/util" - "github.com/bluesky-social/indigo/xrpc" - - "github.com/flosch/pongo2/v6" - "github.com/labstack/echo-contrib/echoprometheus" - "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" - slogecho "github.com/samber/slog-echo" - "github.com/urfave/cli/v2" -) - -//go:embed static/* -var StaticFS embed.FS - -type Server struct { - echo *echo.Echo - httpd *http.Server - dir identity.Directory // TODO: unused? - xrpcc *xrpc.Client - defaultHandle syntax.Handle -} - -func serve(cctx *cli.Context) error { - debug := cctx.Bool("debug") - httpAddress := cctx.String("bind") - appviewHost := cctx.String("appview-host") - - dh, err := syntax.ParseHandle("atproto.com") - if err != nil { - return err - } - - xrpcc := &xrpc.Client{ - Client: util.RobustHTTPClient(), - Host: appviewHost, - // Headers: version - } - e := echo.New() - - // httpd - var ( - httpTimeout = 1 * time.Minute - httpMaxHeaderBytes = 1 * (1024 * 1024) - ) - - srv := &Server{ - echo: e, - xrpcc: xrpcc, - dir: identity.DefaultDirectory(), - defaultHandle: dh, - } - srv.httpd = &http.Server{ - Handler: srv, - Addr: httpAddress, - WriteTimeout: httpTimeout, - ReadTimeout: httpTimeout, - MaxHeaderBytes: httpMaxHeaderBytes, - } - - e.HideBanner = true - e.Use(slogecho.New(slog)) - e.Use(middleware.Recover()) - e.Use(echoprometheus.NewMiddleware("athome")) - e.Use(middleware.BodyLimit("64M")) - e.HTTPErrorHandler = srv.errorHandler - e.Renderer = NewRenderer("templates/", &TemplateFS, debug) - e.Use(middleware.SecureWithConfig(middleware.SecureConfig{ - ContentTypeNosniff: "nosniff", - XFrameOptions: "SAMEORIGIN", - HSTSMaxAge: 31536000, // 365 days - // TODO: - // ContentSecurityPolicy - // XSSProtection - })) - - // redirect trailing slash to non-trailing slash. - // all of our current endpoints have no trailing slash. - e.Use(middleware.RemoveTrailingSlashWithConfig(middleware.TrailingSlashConfig{ - RedirectCode: http.StatusFound, - })) - - staticHandler := http.FileServer(func() http.FileSystem { - if debug { - return http.FS(os.DirFS("static")) - } - fsys, err := fs.Sub(StaticFS, "static") - if err != nil { - slog.Error("static template error", "err", err) - os.Exit(-1) - } - return http.FS(fsys) - }()) - - e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", staticHandler))) - e.GET("/_health", srv.HandleHealthCheck) - e.GET("/metrics", echoprometheus.NewHandler()) - - // basic static routes - e.GET("/robots.txt", echo.WrapHandler(staticHandler)) - e.GET("/favicon.ico", echo.WrapHandler(staticHandler)) - - // actual content - e.GET("/", srv.WebHome) - e.GET("/bsky", srv.WebProfile) - e.GET("/bsky/post/:rkey", srv.WebPost) - e.GET("/bsky/repo.car", srv.WebRepoCar) - e.GET("/bsky/rss.xml", srv.WebRepoRSS) - - // Start the server - slog.Info("starting server", "bind", httpAddress) - go func() { - if err := srv.httpd.ListenAndServe(); err != nil { - if !errors.Is(err, http.ErrServerClosed) { - slog.Error("HTTP server shutting down unexpectedly", "err", err) - } - } - }() - - // Wait for a signal to exit. - slog.Info("registering OS exit signal handler") - quit := make(chan struct{}) - exitSignals := make(chan os.Signal, 1) - signal.Notify(exitSignals, syscall.SIGINT, syscall.SIGTERM) - go func() { - sig := <-exitSignals - slog.Info("received OS exit signal", "signal", sig) - - // Shut down the HTTP server - if err := srv.Shutdown(); err != nil { - slog.Error("HTTP server shutdown error", "err", err) - } - - // Trigger the return that causes an exit. - close(quit) - }() - <-quit - slog.Info("graceful shutdown complete") - return nil -} - -type GenericStatus struct { - Daemon string `json:"daemon"` - Status string `json:"status"` - Message string `json:"msg,omitempty"` -} - -func (srv *Server) errorHandler(err error, c echo.Context) { - code := http.StatusInternalServerError - if he, ok := err.(*echo.HTTPError); ok { - code = he.Code - } - if code >= 500 { - slog.Warn("athome-http-internal-error", "err", err) - } - data := pongo2.Context{ - "statusCode": code, - } - c.Render(code, "error.html", data) -} - -func (srv *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - srv.echo.ServeHTTP(rw, req) -} - -func (srv *Server) Shutdown() error { - slog.Info("shutting down") - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - return srv.httpd.Shutdown(ctx) -} - -func (s *Server) HandleHealthCheck(c echo.Context) error { - return c.JSON(200, GenericStatus{Status: "ok", Daemon: "athome"}) -} diff --git a/cmd/athome/static/apple-touch-icon.png b/cmd/athome/static/apple-touch-icon.png deleted file mode 100644 index 5ebb6787c999108d56d1b2f2aa4a5f2275ac5e37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14742 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 diff --git a/cmd/athome/static/default-avatar.png b/cmd/athome/static/default-avatar.png deleted file mode 100644 index c732d942b33e04f1be7a9dced9211ec676de1056..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1624 zcmeAS@N?(olHy`uVBq!ia0y~yVDMpJVDRQ(Vqjnh{qXGw0|T49r;B4q#hkaZbA6_! zN*u3WVsTDN>99>ltFwt^AD@{)p|9<$64|ik3kkxx$-WWOiVti$8`c+@JM9qr4Bi_> zXQ%7x3Wx7}Skr9Tuj+lW%)yyaxK&gCkp-94uZDvb=WFME-Xq8Hx4!z_^Ih*=|F?f` z`F!X5*Sp>=Xl!IWW<5_jm#Oi9@x;fh=Uw{5eN0NfP4kO68=@s`NKTOPgXo@*x7^oZPi zyYSA@d7oEp^-SD6Y43zNDTj2}1dQEMwzseM3#^gy-~aDqTOz00`GeC^tCmVBY+BNm zd;GhZrN>@PD~`L7h`yAl+z@}K`c1{;Bh!zRXXk(Tcz(`~MdqijO|6-zv`Nf5@L! zJ>gUFE~dz)ouL~4jGop_eyX>Z>$-|Y5XY3%4Qh_zI{x-g?c&snl)lfoE?Qc|v2=Cl zjp^&siaOSH?BnRR_PPn%B2v7U-%B?w%UU4I{xEOx(#zEWI+w1l(H2VJ z9jwQvUZBy(}Rs;+JI>Omy;!)7f;oBlq|{?hw-z8`ftfyk}*8XLoikc0-_F+I+9nY`du_h@%8s|8Uu;C~ zysbR(O>0uuihOgOMN{@v*h_BhjsDKlZPno^>`~i#eNnqH^Zu;?Kh9<_*i$#Vf`6^w!w%I*89(wpz)f)$|I31&NSyrN-6;$=bW-eHH&C(6b zvbkKM^~@0@YbA60|L4xFk*sGO?8KSznW1QPu8ko;mG_j>&;E(d|Vi*WTYGzUk?TZxb}l z?rqzgwQf=0&g}A)Sr3+5l}d~2r|66H&kj;MQU2lI>oeD;Oe)&G@wd*>O`%$fCet_% z={&K#;uIPN3&^!b!L zqo>~Gb>Ai@igC^Tm+aCSxc6j2tHU`ZzuE&LtaqDR{dTH3yV^2qmz@@!t$T3J&k3v- z|E_cl^{LM)%v2`77wE~4TU5Zb_r{(OgBkAwu9&P;nz&Va z>efzWw`ZfU9!8& z&67FGkz3|X$jydTV)y@^J0}0)ZFNy*mG%pTJ+rFf=N|0a9`W+=enCD6F6FOB~ zh2=fpge*G5vHimzm4^2I7j*~TR-2SQ$a~yByQ$=xgw-FTmcqK8liZJgI?NJz{4?WW o#NpsVp>H!!d~90o^kjd*Yh$nGg-&}J7#J8lUHx3vIVCg!0O3p$mjD0& diff --git a/cmd/athome/static/favicon-16x16.png b/cmd/athome/static/favicon-16x16.png deleted file mode 100644 index 4267562b808197d5b00b58f3ffdedde4b689b3c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 316 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7nLS+`LoEE4h8S`kauAr~ znXdTa@fud{jRGv(2OAO;mAJb6KQwFIxNmharl>PLL?mg_?z=PZ?wu)Mo4xSuwS-IU zk?ahmw*TLL4EZm4V)Zw_9g3=KWe!P`l`giYpY&fLwBnN=<4$G6Et{2g@tesDsPY}? zvWV-LSUfc(zG`o4!Cn=Eq&I60z5AV~vww+-8dHUA@YcC)-#Ri`6wFST7b~VQI?UBP z_U8I0Ys35%3tpOhvQ7G^f8Y~)!-A6Vf+P=Ug_CHvJE`*K V@_u*pU|?Wi@O1TaS?83{1OOS_e`^2$ diff --git a/cmd/athome/static/favicon-32x32.png b/cmd/athome/static/favicon-32x32.png deleted file mode 100644 index 869f6df5fc6bdd2c78f2ac91679fb6814f999485..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANM!Cp=voLn7SQhVRV^aTNJ? z?x=|thh59mt-TMtJvLl+Di9Uyb#!tO5o~?npD(#vVPA`YK(@C0A+1{~XDZU(&E5Tc z-dtnj@|&8QZqBu=zyDKx$>z8EkComnIILR{!}_Ok-=YfHf4@FP`wQ;dE??*S|Hn`L zW!8r{`94nlr*iE;Zar)Ck25jrKOZjsbCcVzsfcR}cl^FDPj1dI{`XK~dBg+mziKR} z^&d*d-)ZY;H{*apnF2}VvG9j!;jSyANoi9X!T5Z+7f-?nuvEv zWYsV49q*g$Z@txZj1ErwIxn&Qfm6z@%&FX4JQE}hjz=UWx$P?9;E!zdoojl>rNTrb zKxvv*)Wv+ujS|d^i;u5qXl;Bd6+7culEw>8f2r7j=Iv$qJ7#WB7P%l6UFx`dNyOil zl(YIJ9B;H(QbgCVE*IJ3SJkF+aPuT?k?U%TuL6&nw%9s1dPFoFe#N`59|wVvq6EYR*NG<|*i0k8ARYPr*$$BWLNdh$nm~)O+W164QsIPo3e$=4;Xn!Z!DEi1>8;y2_Ji%KcnffBD=9 zzh>(wfA4KQU+wdp)8BkbHmhp9yJ5~U;Ry|ozwUW`z4+1BJ=0{@dL3J2zvlTlS;o7H e^S-_QS+9J7zr7+tu!n(xfx*+&&t;ucLK6T@oM(;z diff --git a/cmd/athome/static/favicon.ico b/cmd/athome/static/favicon.ico deleted file mode 100644 index b4290a797a9f7ae4d14373ff1608be81d5940725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 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 aVb=d72Jin73{tQ(19I;u9t{CXLjVA0l*gw4 diff --git a/cmd/athome/static/favicon.png b/cmd/athome/static/favicon.png deleted file mode 100644 index 61cf7c943b6ac083ab0752f283391e37b39c1221..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6405 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 Q6Eu|X>FVdQ&MBb@0K66k1ONa4 diff --git a/cmd/athome/static/robots.txt b/cmd/athome/static/robots.txt deleted file mode 100644 index 4f8510d1..00000000 --- a/cmd/athome/static/robots.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Hello Friends! -# If you are considering bulk or automated crawling, you may want to look in -# to our protocol (API), including a firehose of updates. See: https://atproto.com/ - -# By default, may crawl anything on this domain. HTTP 429 ("backoff") status -# codes are used for rate-limiting. Up to a handful concurrent requests should -# be ok. -User-Agent: * -Allow: / diff --git a/cmd/athome/templates/base.html b/cmd/athome/templates/base.html deleted file mode 100644 index 75dd3ba0..00000000 --- a/cmd/athome/templates/base.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - {%- block head_title -%}Bluesky{%- endblock -%} - - - - - - - - - {% block html_head_extra -%}{%- endblock %} - - - - -{%- block body_all %} -
-
-
- -
-
- {% block main_content %}blank page{% endblock %} -
-
-
-{% endblock -%} - - diff --git a/cmd/athome/templates/error.html b/cmd/athome/templates/error.html deleted file mode 100644 index 53d0a118..00000000 --- a/cmd/athome/templates/error.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends "base.html" %} - -{% block head_title %}Error {{ statusCode }} - Bluesky{% endblock %} - -{% block main_content %} -
-
-

{{ statusCode }}

-

Error!

-

Sorry about that! The Bluesky Status Page might have more context. -

-{% endblock %} diff --git a/cmd/athome/templates/feed_macros.html b/cmd/athome/templates/feed_macros.html deleted file mode 100644 index 6d444bf1..00000000 --- a/cmd/athome/templates/feed_macros.html +++ /dev/null @@ -1,93 +0,0 @@ - -{% macro feed_post(feedItem, selfDID, primary) export %} -{% if primary %} -
-{% else %} -
-{% endif %} -
- {% if feedItem.Post.Author.Avatar %} - - {% else %} - - {% endif %} -
-
- {% if feedItem.Reason %} - {{ feedItem.Reason.FeedDefs_ReasonRepost }} - {% endif %} -
- {% if feedItem.Post.Author.Did == selfDID %} - - {% else %} - - {% endif %} - {% if feedItem.Post.Author.DisplayName %} - {{ feedItem.Post.Author.DisplayName }} - - {% else %} - - {% endif %} - @{{ feedItem.Post.Author.Handle }} - - -
- {# TODO: relative time#} - {# TODO: parse and fix link (custom filter?) #} - {% if feedItem.Post.Author.Did == selfDID %} - {{ feedItem.Post.IndexedAt }} - {% else %} - {{ feedItem.Post.IndexedAt }} - {% endif %} -
-
-
- {{ feedItem.Post.Record.Val.Text }} - {% if feedItem.Post.Embed and feedItem.Post.Embed.EmbedImages_View %} -
- {% for image in feedItem.Post.Embed.EmbedImages_View.Images %} -
-
- - {{ image.Alt }} - -
-
- {% endfor %} -
- {% endif %} -
- -
-
- -{% if primary %} - -{% endif %} -{% endmacro %} - -{% macro thread_parents(post, selfDID, primary) export %} -{% if post.Parent %} - {{ thread_parents(post.Parent.FeedDefs_ThreadViewPost, selfDID, false) }} -
-{% endif %} -{{ feed_post(post, selfDID, primary) }} -{% endmacro %} - -{% macro thread_children(post, selfDID) export %} -{% for child in post.Replies %} -
- {{ feed_post(child.FeedDefs_ThreadViewPost, selfDID) }} - {{ thread_children(child.FeedDefs_ThreadViewPost, selfDID) }} -{% endfor %} -{% endmacro %} diff --git a/cmd/athome/templates/post.html b/cmd/athome/templates/post.html deleted file mode 100644 index ee4db544..00000000 --- a/cmd/athome/templates/post.html +++ /dev/null @@ -1,55 +0,0 @@ -{% extends "base.html" %} - -{% block head_title %} -{%- if postView.Post -%} - @{{ postView.Post.Author.Handle }} on Bluesky -{%- else -%} - Bluesky -{%- endif -%} -{% endblock %} - -{% block sidebar_title %} -{%- if postView.Post -%} - {{ postView.Post.Author.Handle }} -{%- else -%} - Bluesky -{%- endif -%} -{% endblock %} - -{% block html_head_extra -%} -{%- if postView.Post -%} - - - {%- if requestURI %} - - {% endif -%} - {%- if postView.Post.Author.DisplayName %} - - {% else %} - - {% endif -%} - {%- if postView.Post.Record.Val.Text %} - - - {% endif -%} - {%- if imgThumbUrl %} - - - {%- elif postView.Post.Author.Avatar %} - {# Don't use avatar image in cards; usually looks bad #} - - {% endif %} - - - -{% endif -%} -{%- endblock %} - -{% block main_content %} - {% import "feed_macros.html" feed_post, thread_parents, thread_children %} -
-
- {{ thread_parents(postView, did, true) }} - {{ thread_children(postView) }} -
-{%- endblock %} diff --git a/cmd/athome/templates/profile.html b/cmd/athome/templates/profile.html deleted file mode 100644 index 7110bf0e..00000000 --- a/cmd/athome/templates/profile.html +++ /dev/null @@ -1,75 +0,0 @@ -{% extends "base.html" %} - -{% block head_title %} -{%- if profileView -%} - @{{ profileView.Handle }} on Bluesky -{%- else -%} - Bluesky -{%- endif -%} -{% endblock %} - -{% block sidebar_title %} -{%- if profileView -%} - {{ profileView.Handle }} -{%- else -%} - Bluesky -{%- endif -%} -{% endblock %} - -{% block html_head_extra -%} -{%- if profileView -%} - - - {%- if requestURI %} - - {% endif -%} - {%- if profileView.DisplayName %} - - {% else %} - - {% endif -%} - {%- if profileView.Description %} - - - {% endif -%} - {%- if profileView.Banner %} - - - {%- elif profileView.Avatar -%} - {# Don't use avatar image in cards; usually looks bad #} - - {% endif %} - - - -{% endif -%} -{%- endblock %} - -{% block main_content %} - {% import "feed_macros.html" feed_post %} - {% if profileView.Banner %} - -
- {% endif %} - {% if profileView.DisplayName %} -

{{ profileView.DisplayName }}

- {% else %} -

{{ profileView.Handle}}

- {% endif %} -

@{{ profileView.Handle }}

-

{{ profileView.Did }}

-

- {{ profileView.FollowersCount }} followers | - {{ profileView.FollowsCount }} following | - {{ profileView.PostsCount }} posts -

-

{{ profileView.Description }}

- -
-
- {% for feedItem in authorFeed %} - {{ feed_post(feedItem, did) }} -
- {% endfor %} -
-{%- endblock %}