package main import ( "fmt" "net/http" "strings" "github.com/PuerkitoBio/goquery" "github.com/muesli/termenv" ) func trendingLang(lang string, timeframes []string) (Language, error) { l := Language{ Repositories: make([]Repository, 0), } repoMap := make(map[Repository]struct{}) for _, timeframe := range timeframes { la, err := trendingRepos(lang, timeframe) if err != nil { return la, err } l.Color = la.Color for _, r := range la.Repositories { repoMap[r] = struct{}{} } } for repo := range repoMap { l.Repositories = append(l.Repositories, repo) } return l, nil } func trendingRepos(lang, timeframe string) (Language, error) { u := fmt.Sprintf("https://github.com/trending/%s?since=%s", lang, timeframe) res, err := http.Get(u) if err != nil { return Language{}, err } defer res.Body.Close() doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { return Language{}, err } var l Language doc.Find(".Box-row").Each(func(_ int, s *goquery.Selection) { if l.Color == "" { rlcStyle, _ := s.Find(".repo-language-color").Attr("style") l.Color = strings.Fields(rlcStyle)[1] } e := s.Find("h1 a") repo := strings.Join(strings.Fields(e.Text()), "") d := strings.TrimSpace(s.Find("p").Text()) l.Repositories = append(l.Repositories, Repository{Name: repo, Description: d}) }) return l, nil } type Language struct { Color string `json:"color"` Repositories []Repository `json:"repositories"` } type Repository struct { Name string `json:"name"` Description string `json:"description"` } func (r Repository) Link() string { return termenv.Hyperlink(fmt.Sprintf("https://github.com/%s", r.Name), r.Name) }