gostart/page.go

205 lines
4.2 KiB
Go
Raw Normal View History

2022-11-29 19:55:00 -07:00
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
2022-12-04 19:03:59 -07:00
"log"
2022-11-29 19:55:00 -07:00
"net/http"
"sort"
"time"
"suah.dev/gostart/data"
"tailscale.com/tailcfg"
)
const gqEndPoint = "https://api.github.com/graphql"
const graphQuery = `
{
search(
query: "is:open is:public archived:false repo:%s in:title %s",
2022-11-29 19:55:00 -07:00
type: ISSUE,
first: 20
) {
issueCount
edges {
node {
... on Issue {
number
title
url
repository {
nameWithOwner
}
createdAt
}
... on PullRequest {
number
title
repository {
nameWithOwner
}
createdAt
url
}
}
}
}
rateLimit {
remaining
resetAt
}
}
`
type GQLQuery struct {
Query string `json:"query"`
}
func getData(q GQLQuery, token string) (*WatchResult, error) {
var req *http.Request
var err error
var re = &WatchResult{}
client := &http.Client{}
buf := new(bytes.Buffer)
if err := json.NewEncoder(buf).Encode(q); err != nil {
return nil, err
}
req, err = http.NewRequest("POST", gqEndPoint, buf)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", token))
res, err := client.Do(req)
if err != nil {
return nil, err
}
2022-12-04 19:03:59 -07:00
defer func() {
err := res.Body.Close()
if err != nil {
2022-12-05 15:45:39 -07:00
log.Fatal("can't close body: ", err)
2022-12-04 19:03:59 -07:00
}
}()
2022-11-29 19:55:00 -07:00
if err = json.NewDecoder(res.Body).Decode(re); err != nil {
return nil, err
}
return re, nil
}
type Page struct {
Title string
PullRequests []data.PullRequest
Links []data.Link
Node tailcfg.Node
Watches WatchResults
CurrentLimits *RateLimit
2022-12-04 19:03:59 -07:00
Ignores []data.PullRequestIgnore
2022-11-29 19:55:00 -07:00
}
func (p *Page) Sort() {
sort.Slice(p.Links, func(i, j int) bool {
2022-12-02 20:53:05 -07:00
return p.Links[i].Name < p.Links[j].Name
2022-11-29 19:55:00 -07:00
})
sort.Slice(p.PullRequests, func(i, j int) bool {
return p.PullRequests[i].Number > p.PullRequests[j].Number
})
sort.Slice(p.Watches, func(i, j int) bool {
return p.Watches[i].Name < p.Watches[j].Name
})
for _, w := range p.Watches {
sort.Slice(w.Data.Search.Edges, func(i, j int) bool {
return w.Data.Search.Edges[i].Node.CreatedAt.After(w.Data.Search.Edges[j].Node.CreatedAt)
})
}
}
type WatchResults []WatchResult
2022-12-04 19:03:59 -07:00
func (w *WatchResults) forID(ownerID int64) WatchResults {
2022-11-29 19:55:00 -07:00
newResults := WatchResults{}
2022-12-04 19:03:59 -07:00
for _, r := range *w {
2022-11-29 19:55:00 -07:00
if r.OwnerID == ownerID {
newResults = append(newResults, r)
}
}
return newResults
}
func (w WatchResults) GetLimits() *RateLimit {
2022-12-02 20:53:05 -07:00
rl := &RateLimit{}
2022-11-29 19:55:00 -07:00
sort.Slice(w, func(i, j int) bool {
return w[i].Data.RateLimit.Remaining < w[j].Data.RateLimit.Remaining
})
2022-12-02 20:53:05 -07:00
if len(w) > 0 {
rl = &w[0].Data.RateLimit
}
return rl
2022-11-29 19:55:00 -07:00
}
func (w *WatchResults) Update(ghToken string) error {
ctx := context.Background()
watches, err := app.queries.GetAllWatchItems(ctx)
if err != nil {
return err
}
for _, watch := range watches {
qd := GQLQuery{Query: fmt.Sprintf(graphQuery, watch.Repo, watch.Name)}
2022-11-29 19:55:00 -07:00
wr, err := getData(qd, ghToken)
if err != nil {
return err
}
// TODO: cross ref the list of ignores and prune the wr accordingly
wr.OwnerID = watch.OwnerID
wr.Name = watch.Name
wr.Repo = watch.Repo
2022-11-29 19:55:00 -07:00
*w = append(*w, *wr)
}
return nil
}
type WatchResult struct {
Data Data `json:"data,omitempty"`
OwnerID int64
Name string
Repo string
2022-11-29 19:55:00 -07:00
}
type Repository struct {
NameWithOwner string `json:"nameWithOwner,omitempty"`
}
type Node struct {
Number int `json:"number,omitempty"`
Title string `json:"title,omitempty"`
Repository Repository `json:"repository,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
URL string `json:"url,omitempty"`
}
type Edges struct {
Node Node `json:"node,omitempty"`
}
type Search struct {
IssueCount int `json:"issueCount,omitempty"`
Edges []Edges `json:"edges,omitempty"`
}
2022-12-04 19:03:59 -07:00
2022-11-29 19:55:00 -07:00
type RateLimit struct {
Remaining int `json:"remaining,omitempty"`
ResetAt time.Time `json:"resetAt,omitempty"`
}
type Data struct {
Search Search `json:"search,omitempty"`
RateLimit RateLimit `json:"rateLimit,omitempty"`
}