tiny 88x31 lexicon for atproto
0
fork

Configure Feed

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

some like things

+138 -48
+91 -42
db/lexicon.go
··· 8 8 "time" 9 9 ) 10 10 11 - func (s *Store) GetButtonsAuth(limit int, cursor *string, ctx context.Context, did string) ([]types.ButtonViewAuth, time.Time, error) { 12 - query := ` 13 - SELECT 14 - b.uri, 15 - b.did, 16 - b.alt, 17 - b.href, 18 - b.posted_at, 19 - b.like_count, 20 - FROM buttons b 21 - ORDER BY posted_at DESC 22 - %s 23 - LIMIT $1 24 - ` 25 - if cursor != nil { 26 - query = fmt.Sprintf(query, "WHERE posted_at < $2") 27 - } else { 28 - query = fmt.Sprintf(query, "") 29 - } 30 - rows, err := s.pool.Query(ctx, query, limit, cursor) 31 - if err != nil { 32 - if err == pgx.ErrNoRows { 33 - return nil, time.Time{}, nil 34 - } 35 - return nil, time.Time{}, err 36 - } 37 - defer rows.Close() 38 - var buttons = make([]types.ButtonViewAuth, 0) 39 - var postedAt time.Time 40 - for rows.Next() { 41 - var btnView types.ButtonViewAuth 42 - err := rows.Scan(&btnView.Src, &btnView.DID, &btnView.Alt, &btnView.HREF, &postedAt, &btnView.Likes, &btnView.Liked) 43 - if err != nil { 44 - return nil, time.Time{}, err 45 - } 46 - btnView.Src = fmt.Sprintf("/xrpc/store.88x31.getButton?uri=%s", btnView.Src) 47 - buttons = append(buttons, btnView) 48 - } 49 - return buttons, postedAt, nil 50 - } 51 - 11 + // func (s *Store) GetButtonsAuth(limit int, cursor *string, ctx context.Context, did string) ([]types.ButtonViewAuth, time.Time, error) { 12 + // query := ` 13 + // SELECT 14 + // uri, 15 + // cid, 16 + // did, 17 + // alt, 18 + // href, 19 + // posted_at, 20 + // like_count 21 + // FROM buttons 22 + // ORDER BY posted_at DESC 23 + // %s 24 + // LIMIT $1 25 + // ` 26 + // var rows pgx.Rows 27 + // var err error 28 + // if cursor != nil { 29 + // query = fmt.Sprintf(query, "WHERE posted_at < $3") 30 + // rows, err = s.pool.Query(ctx, query, limit, did, cursor) 31 + // } else { 32 + // query = fmt.Sprintf(query, "") 33 + // rows, err = s.pool.Query(ctx, query, limit, did) 34 + // } 35 + // if err != nil { 36 + // if err == pgx.ErrNoRows { 37 + // return nil, time.Time{}, nil 38 + // } 39 + // return nil, time.Time{}, err 40 + // } 41 + // defer rows.Close() 42 + // var buttons = make([]types.ButtonViewAuth, 0) 43 + // var postedAt time.Time 44 + // for rows.Next() { 45 + // var btnView types.ButtonViewAuth 46 + // err := rows.Scan(&btnView.URI, &btnView.DID, &btnView.Alt, &btnView.HREF, &postedAt, &btnView.Likes, &btnView.Liked) 47 + // if err != nil { 48 + // return nil, time.Time{}, err 49 + // } 50 + // buttons = append(buttons, btnView) 51 + // } 52 + // return buttons, postedAt, nil 53 + // } 52 54 func (s *Store) GetButtons(limit int, cursor *string, ctx context.Context) ([]types.ButtonView, time.Time, error) { 53 55 query := ` 54 56 SELECT 55 57 uri, 58 + cid, 56 59 did, 57 60 alt, 58 61 href, ··· 86 89 var postedAt time.Time 87 90 for rows.Next() { 88 91 var btnView types.ButtonView 89 - err := rows.Scan(&btnView.URI, &btnView.DID, &btnView.Alt, &btnView.HREF, &postedAt, &btnView.Likes) 92 + err := rows.Scan(&btnView.URI, &btnView.CID, &btnView.DID, &btnView.Alt, &btnView.HREF, &postedAt, &btnView.Likes) 90 93 if err != nil { 91 94 return nil, time.Time{}, err 92 95 } 93 96 buttons = append(buttons, btnView) 94 97 } 95 98 return buttons, postedAt, nil 99 + } 100 + 101 + func (s *Store) GetButtonAuth(uri string, ctx context.Context, did string) (*types.ButtonViewAuth, error) { 102 + row := s.pool.QueryRow(ctx, ` 103 + SELECT 104 + did, 105 + alt, 106 + href, 107 + cid, 108 + posted_at, 109 + like_count 110 + FROM buttons 111 + WHERE uri = $1 112 + `, uri) 113 + var btn types.Button 114 + err := row.Scan(&btn.DID, 115 + &btn.Alt, 116 + &btn.HREF, 117 + &btn.CID, 118 + &btn.PostedAt, 119 + &btn.Likes) 120 + if err != nil { 121 + return nil, err 122 + } 123 + row = s.pool.QueryRow(ctx, 124 + `CASE 125 + WHEN EXISTS ( 126 + SELECT 1 127 + FROM likes 128 + WHERE did = $1 AND subject_uri = $2 AND subject_cid = $3 129 + ) THEN TRUE 130 + ELSE FALSE 131 + END AS is_liked`, did, btn.URI, btn.CID, 132 + ) 133 + var btna types.ButtonViewAuth 134 + btna.URI = uri 135 + btna.CID = btn.CID 136 + btna.DID = btn.DID 137 + btna.Alt = btn.Alt 138 + btna.HREF = btn.HREF 139 + btna.Likes = btn.Likes 140 + err = row.Scan(&btna.Liked) 141 + if err != nil { 142 + return nil, err 143 + } 144 + return &btna, nil 96 145 } 97 146 98 147 func (s *Store) GetButton(uri string, ctx context.Context) (*types.Button, error) {
+33 -3
handler/handler.go
··· 116 116 } 117 117 118 118 func (h *Handler) getbutton(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) { 119 + if cs != nil { 120 + h.getbuttonauth(cs, w, r) 121 + return 122 + } 119 123 uri := r.URL.Query().Get("uri") 120 124 btn, err := h.db.GetButton(uri, r.Context()) 121 125 if err != nil || btn == nil { ··· 128 132 Button types.Button 129 133 } 130 134 var btnd ButtonData 131 - if cs != nil { 132 - did := cs.Data.AccountDID.String() 133 - btnd.DID = &did 135 + if btn.Alt != nil { 136 + btnd.Title = *btn.Alt 137 + } else { 138 + btnd.Title = uri 134 139 } 140 + btnd.Button = *btn 141 + err = buttonT.ExecuteTemplate(w, "base.html", btnd) 142 + if err != nil { 143 + http.Error(w, "error templating", http.StatusInternalServerError) 144 + } 145 + } 146 + 147 + func (h *Handler) getbuttonauth(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) { 148 + if cs == nil { 149 + panic("cs must be non nil when i call getbuttonauth") 150 + } 151 + did := cs.Data.AccountDID.String() 152 + uri := r.URL.Query().Get("uri") 153 + btn, err := h.db.GetButtonAuth(uri, r.Context(), did) 154 + if err != nil || btn == nil { 155 + http.Error(w, "not found", http.StatusNotFound) 156 + return 157 + } 158 + type ButtonData struct { 159 + DID *string 160 + Title string 161 + Button types.ButtonViewAuth 162 + } 163 + var btnd ButtonData 164 + btnd.DID = &did 135 165 if btn.Alt != nil { 136 166 btnd.Title = *btn.Alt 137 167 } else {
+1 -1
handler/upload.go
··· 59 59 http.Error(w, "error storing like", http.StatusInternalServerError) 60 60 return 61 61 } 62 - http.Redirect(w, r, r.URL.Path, http.StatusCreated) 62 + http.Redirect(w, r, fmt.Sprintf("/button?uri=%s", uri), http.StatusCreated) 63 63 } 64 64 65 65 func (h *Handler) upload(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) {
+8
tmpl/button.html
··· 1 1 {{define "content"}} 2 2 {{template "buttonpart" .Button}} 3 3 {{if .DID}} 4 + {{if .Liked}} 4 5 <form action="/like" method="POST"> 5 6 <input type="text" name="uri" value="{{.Button.URI}}" hidden /> 6 7 <input type="text" name="cid" value="{{.Button.CID}}" hidden /> 7 8 <input type="submit" value='"like"'/> 8 9 </form> 10 + {{else}} 11 + <form action="/like" method="DELETE"> 12 + <input type="text" name="uri" value="{{.Button.URI}}" hidden /> 13 + <input type="text" name="cid" value="{{.Button.CID}}" hidden /> 14 + <input type="submit" value='un-"like"'/> 15 + </form> 16 + {{end}} 9 17 {{end}} 10 18 {{end}}
+5 -2
types/lexicon.go
··· 14 14 CID string 15 15 PostedAt time.Time 16 16 IndexedAt time.Time 17 + Likes int 17 18 } 18 19 19 20 type ButtonView struct { 20 - URI string `json:"src"` 21 + URI string `json:"uri"` 22 + CID string `json:"cid"` 21 23 DID string `json:"did"` 22 24 Alt *string `json:"alt,omitempty"` 23 25 HREF *string `json:"href,omitempty"` ··· 25 27 } 26 28 27 29 type ButtonViewAuth struct { 30 + URI string `json:"uri"` 31 + CID string `json:"cid"` 28 32 DID string `json:"did"` 29 - Src string `json:"src"` 30 33 Alt *string `json:"alt,omitempty"` 31 34 HREF *string `json:"href,omitempty"` 32 35 Likes int `json:"likes"`