An HTML-only Bluesky frontend
at main 195 lines 5.2 kB view raw
1package main 2 3import ( 4 "embed" 5 "encoding/json" 6 "fmt" 7 "io/fs" 8 "log" 9 "net/http" 10 11 "git.sr.ht/~jordanreger/bsky" 12 "git.sr.ht/~jordanreger/bsky/util" 13) 14 15var host = "htmlsky.app" 16var handle = "jordanreger.com" 17var did = "did:plc:27rjcwbur2bizjjx3zakeme5" 18 19//go:embed all:public 20var publicFiles embed.FS 21var publicFS = fs.FS(publicFiles) 22var public, _ = fs.Sub(publicFS, "public") 23 24func main() { 25 mux := http.NewServeMux() 26 27 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 28 if r.URL.Path != "/" { 29 // serve DID 30 if r.URL.Path == "/.well-known/atproto-did" { 31 fmt.Fprint(w, did) 32 return 33 } 34 // otherwise serve static 35 http.ServeFileFS(w, r, public, r.URL.Path) 36 return 37 } 38 39 // serve homepage 40 did := util.GetDID(handle) 41 actor := bsky.GetActorProfile(did) 42 page := GetActorPage(actor) 43 44 fmt.Fprint(w, page) 45 }) 46 47 /* REDIRECTS */ 48 mux.HandleFunc("/raw/", func(w http.ResponseWriter, r *http.Request) { 49 fmt.Fprint(w, "Usage: /raw/profile/{handle}[/post/{rkey}]") 50 }) 51 mux.HandleFunc("/raw/{handle}/", func(w http.ResponseWriter, r *http.Request) { 52 http.Redirect(w, r, "/raw/", http.StatusSeeOther) 53 }) 54 mux.HandleFunc("/raw/profile/{handle}/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 55 http.Redirect(w, r, "/raw/", http.StatusSeeOther) 56 }) 57 mux.HandleFunc("/embed/", func(w http.ResponseWriter, r *http.Request) { 58 fmt.Fprint(w, "Usage: /embed/profile/{handle}[/post/{rkey}]") 59 }) 60 mux.HandleFunc("/embed/{handle}/", func(w http.ResponseWriter, r *http.Request) { 61 http.Redirect(w, r, "/embed/", http.StatusSeeOther) 62 }) 63 mux.HandleFunc("/profile/", func(w http.ResponseWriter, r *http.Request) { 64 http.Redirect(w, r, "/", http.StatusSeeOther) 65 }) 66 mux.HandleFunc("/profile/{handle}/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 67 http.Redirect(w, r, "/", http.StatusSeeOther) 68 }) 69 70 /* ROUTES */ 71 72 // actor 73 mux.HandleFunc("/profile/{handle}/", func(w http.ResponseWriter, r *http.Request) { 74 handle := r.PathValue("handle") 75 76 did := util.GetDID(handle) 77 actor := bsky.GetActorProfile(did) 78 page := GetActorPage(actor) 79 80 fmt.Fprint(w, page) 81 }) 82 mux.HandleFunc("/raw/profile/{handle}/", func(w http.ResponseWriter, r *http.Request) { 83 handle := r.PathValue("handle") 84 85 did := util.GetDID(handle) 86 actor := bsky.GetActorProfile(did) 87 type raw struct { 88 *bsky.Actor 89 *bsky.Feed `json:"feed,omitempty"` 90 } 91 feed := actor.Feed() 92 actor_feed := raw{ 93 &actor, 94 &feed, 95 } 96 res, _ := json.MarshalIndent(actor_feed, "", " ") 97 98 w.Header().Add("Content-Type", "application/json") 99 fmt.Fprint(w, string(res)) 100 }) 101 mux.HandleFunc("/embed/profile/{handle}/", func(w http.ResponseWriter, r *http.Request) { 102 handle := r.PathValue("handle") 103 104 did := util.GetDID(handle) 105 actor := bsky.GetActorProfile(did) 106 page := GetActorPageEmbed(actor) 107 108 fmt.Fprint(w, page) 109 }) 110 111 // thread 112 mux.HandleFunc("/profile/{handle}/post/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 113 handle := r.PathValue("handle") 114 rkey := r.PathValue("rkey") 115 116 did := util.GetDID(handle) 117 at_uri := util.GetPostURI(did, rkey) 118 thread := bsky.GetThread(at_uri) 119 page := GetThreadPage(thread) 120 121 fmt.Fprint(w, page) 122 }) 123 124 mux.HandleFunc("/raw/profile/{handle}/post/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 125 handle := r.PathValue("handle") 126 rkey := r.PathValue("rkey") 127 128 did := util.GetDID(handle) 129 at_uri := util.GetPostURI(did, rkey) 130 res, _ := json.MarshalIndent(bsky.GetThread(at_uri), "", " ") 131 132 w.Header().Add("Content-Type", "application/json") 133 fmt.Fprint(w, string(res)) 134 }) 135 136 mux.HandleFunc("/embed/profile/{handle}/post/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 137 handle := r.PathValue("handle") 138 rkey := r.PathValue("rkey") 139 140 did := util.GetDID(handle) 141 at_uri := util.GetPostURI(did, rkey) 142 thread := bsky.GetThread(at_uri) 143 page := GetThreadPageEmbed(thread) 144 145 fmt.Fprint(w, page) 146 }) 147 148 // list 149 mux.HandleFunc("/profile/{handle}/lists/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 150 handle := r.PathValue("handle") 151 rkey := r.PathValue("rkey") 152 153 did := util.GetDID(handle) 154 at_uri := util.GetListURI(did, rkey) 155 list := bsky.GetList(at_uri) 156 page := GetListPage(list) 157 158 fmt.Fprint(w, page) 159 }) 160 mux.HandleFunc("/raw/profile/{handle}/lists/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 161 handle := r.PathValue("handle") 162 rkey := r.PathValue("rkey") 163 164 did := util.GetDID(handle) 165 at_uri := util.GetListURI(did, rkey) 166 list := bsky.GetList(at_uri) 167 type raw struct { 168 *bsky.List 169 *bsky.Feed `json:"feed,omitempty"` 170 } 171 feed := list.Feed() 172 actor_feed := raw{ 173 &list, 174 &feed, 175 } 176 res, _ := json.MarshalIndent(actor_feed, "", " ") 177 178 w.Header().Add("Content-Type", "application/json") 179 fmt.Fprint(w, string(res)) 180 181 }) 182 mux.HandleFunc("/embed/profile/{handle}/lists/{rkey}/", func(w http.ResponseWriter, r *http.Request) { 183 handle := r.PathValue("handle") 184 rkey := r.PathValue("rkey") 185 186 did := util.GetDID(handle) 187 at_uri := util.GetListURI(did, rkey) 188 list := bsky.GetList(at_uri) 189 page := GetListPageEmbed(list) 190 191 fmt.Fprint(w, page) 192 }) 193 194 log.Fatal(http.ListenAndServe(":8080", mux)) 195}