Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
jolheiser | 7e8761c788 | |
jolheiser | 41648a142f | |
jolheiser | 480035417b |
|
@ -0,0 +1,9 @@
|
||||||
|
# trending
|
||||||
|
|
||||||
|
Get a quick view of trending GitHub repositories.
|
||||||
|
|
||||||
|
By default it aggregates and dedupes Go and Rust for daily, weekly, and monthly trending.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
12
main.go
12
main.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/caarlos0/log"
|
"github.com/caarlos0/log"
|
||||||
|
@ -34,16 +35,17 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Fatal("could not get trending repositories")
|
log.WithError(err).Fatal("could not get trending repositories")
|
||||||
}
|
}
|
||||||
log.Styles[log.InfoLevel] = lipgloss.NewStyle().Foreground(lipgloss.Color(l.color)).Bold(true)
|
log.Styles[log.InfoLevel] = lipgloss.NewStyle().Foreground(lipgloss.Color(l.Color)).Bold(true)
|
||||||
log.Info(lang.Name)
|
log.Info(lang.Name)
|
||||||
log.IncreasePadding()
|
log.IncreasePadding()
|
||||||
for _, repo := range l.repositories {
|
for _, repo := range l.Repositories {
|
||||||
log.WithField("link", repo.link()).Info(repo.name)
|
log.Info(repo.Link())
|
||||||
if repo.description != "" {
|
if repo.Description != "" {
|
||||||
log.IncreasePadding()
|
log.IncreasePadding()
|
||||||
log.Info(repo.description)
|
log.Info(repo.Description)
|
||||||
log.DecreasePadding()
|
log.DecreasePadding()
|
||||||
}
|
}
|
||||||
|
fmt.Println()
|
||||||
}
|
}
|
||||||
log.ResetPadding()
|
log.ResetPadding()
|
||||||
}
|
}
|
||||||
|
|
45
trending.go
45
trending.go
|
@ -6,47 +6,48 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
"github.com/muesli/termenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func trendingLang(lang string, timeframes []string) (language, error) {
|
func trendingLang(lang string, timeframes []string) (Language, error) {
|
||||||
l := language{
|
l := Language{
|
||||||
repositories: make([]repository, 0),
|
Repositories: make([]Repository, 0),
|
||||||
}
|
}
|
||||||
repoMap := make(map[repository]struct{})
|
repoMap := make(map[Repository]struct{})
|
||||||
for _, timeframe := range timeframes {
|
for _, timeframe := range timeframes {
|
||||||
la, err := trendingRepos(lang, timeframe)
|
la, err := trendingRepos(lang, timeframe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return la, err
|
return la, err
|
||||||
}
|
}
|
||||||
l.color = la.color
|
l.Color = la.Color
|
||||||
for _, r := range la.repositories {
|
for _, r := range la.Repositories {
|
||||||
repoMap[r] = struct{}{}
|
repoMap[r] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for repo := range repoMap {
|
for repo := range repoMap {
|
||||||
l.repositories = append(l.repositories, repo)
|
l.Repositories = append(l.Repositories, repo)
|
||||||
}
|
}
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func trendingRepos(lang, timeframe string) (language, error) {
|
func trendingRepos(lang, timeframe string) (Language, error) {
|
||||||
u := fmt.Sprintf("https://github.com/trending/%s?since=%s", lang, timeframe)
|
u := fmt.Sprintf("https://github.com/trending/%s?since=%s", lang, timeframe)
|
||||||
res, err := http.Get(u)
|
res, err := http.Get(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return language{}, err
|
return Language{}, err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
doc, err := goquery.NewDocumentFromReader(res.Body)
|
doc, err := goquery.NewDocumentFromReader(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return language{}, err
|
return Language{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var l language
|
var l Language
|
||||||
doc.Find(".Box-row").Each(func(_ int, s *goquery.Selection) {
|
doc.Find(".Box-row").Each(func(_ int, s *goquery.Selection) {
|
||||||
if l.color == "" {
|
if l.Color == "" {
|
||||||
rlcStyle, _ := s.Find(".repo-language-color").Attr("style")
|
rlcStyle, _ := s.Find(".repo-language-color").Attr("style")
|
||||||
l.color = strings.Fields(rlcStyle)[1]
|
l.Color = strings.Fields(rlcStyle)[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
e := s.Find("h1 a")
|
e := s.Find("h1 a")
|
||||||
|
@ -54,21 +55,21 @@ func trendingRepos(lang, timeframe string) (language, error) {
|
||||||
|
|
||||||
d := strings.TrimSpace(s.Find("p").Text())
|
d := strings.TrimSpace(s.Find("p").Text())
|
||||||
|
|
||||||
l.repositories = append(l.repositories, repository{name: repo, description: d})
|
l.Repositories = append(l.Repositories, Repository{Name: repo, Description: d})
|
||||||
})
|
})
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type language struct {
|
type Language struct {
|
||||||
color string
|
Color string `json:"color"`
|
||||||
repositories []repository
|
Repositories []Repository `json:"repositories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type repository struct {
|
type Repository struct {
|
||||||
name string
|
Name string `json:"name"`
|
||||||
description string
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r repository) link() string {
|
func (r Repository) Link() string {
|
||||||
return fmt.Sprintf("https://github.com/%s", r.name)
|
return termenv.Hyperlink(fmt.Sprintf("https://github.com/%s", r.Name), r.Name)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue