Merge branch 'main' into lobsters-widget

This commit is contained in:
Svilen Markov
2024-06-02 18:19:06 +01:00
committed by GitHub
42 changed files with 1026 additions and 168 deletions

View File

@@ -22,6 +22,7 @@ type Bookmarks struct {
HideArrow bool `yaml:"hide-arrow"`
} `yaml:"links"`
} `yaml:"groups"`
Style string `yaml:"style"`
}
func (widget *Bookmarks) Initialize() error {

View File

@@ -13,6 +13,8 @@ type HackerNews struct {
widgetBase `yaml:",inline"`
Posts feed.ForumPosts `yaml:"-"`
Limit int `yaml:"limit"`
SortBy string `yaml:"sort-by"`
ExtraSortBy string `yaml:"extra-sort-by"`
CollapseAfter int `yaml:"collapse-after"`
CommentsUrlTemplate string `yaml:"comments-url-template"`
ShowThumbnails bool `yaml:"-"`
@@ -29,18 +31,24 @@ func (widget *HackerNews) Initialize() error {
widget.CollapseAfter = 5
}
if widget.SortBy != "top" && widget.SortBy != "new" && widget.SortBy != "best" {
widget.SortBy = "top"
}
return nil
}
func (widget *HackerNews) Update(ctx context.Context) {
posts, err := feed.FetchHackerNewsTopPosts(40, widget.CommentsUrlTemplate)
posts, err := feed.FetchHackerNewsPosts(widget.SortBy, 40, widget.CommentsUrlTemplate)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return
}
posts.CalculateEngagement()
posts.SortByEngagement()
if widget.ExtraSortBy == "engagement" {
posts.CalculateEngagement()
posts.SortByEngagement()
}
if widget.Limit < len(posts) {
posts = posts[:widget.Limit]

View File

@@ -46,14 +46,15 @@ func statusCodeToStyle(status int) string {
type Monitor struct {
widgetBase `yaml:",inline"`
Sites []struct {
Title string `yaml:"title"`
Url string `yaml:"url"`
IconUrl string `yaml:"icon"`
SameTab bool `yaml:"same-tab"`
Status *feed.SiteStatus `yaml:"-"`
StatusText string `yaml:"-"`
StatusStyle string `yaml:"-"`
Title string `yaml:"title"`
Url OptionalEnvString `yaml:"url"`
IconUrl string `yaml:"icon"`
SameTab bool `yaml:"same-tab"`
Status *feed.SiteStatus `yaml:"-"`
StatusText string `yaml:"-"`
StatusStyle string `yaml:"-"`
} `yaml:"sites"`
Style string `yaml:"style"`
}
func (widget *Monitor) Initialize() error {
@@ -66,7 +67,7 @@ func (widget *Monitor) Update(ctx context.Context) {
requests := make([]*http.Request, len(widget.Sites))
for i := range widget.Sites {
request, err := http.NewRequest("GET", widget.Sites[i].Url, nil)
request, err := http.NewRequest("GET", string(widget.Sites[i].Url), nil)
if err != nil {
message := fmt.Errorf("failed to create http request for %s: %s", widget.Sites[i].Url, err)

View File

@@ -17,6 +17,10 @@ type Reddit struct {
Subreddit string `yaml:"subreddit"`
Style string `yaml:"style"`
ShowThumbnails bool `yaml:"show-thumbnails"`
SortBy string `yaml:"sort-by"`
TopPeriod string `yaml:"top-period"`
Search string `yaml:"search"`
ExtraSortBy string `yaml:"extra-sort-by"`
CommentsUrlTemplate string `yaml:"comments-url-template"`
Limit int `yaml:"limit"`
CollapseAfter int `yaml:"collapse-after"`
@@ -36,6 +40,14 @@ func (widget *Reddit) Initialize() error {
widget.CollapseAfter = 5
}
if !isValidRedditSortType(widget.SortBy) {
widget.SortBy = "hot"
}
if !isValidRedditTopPeriod(widget.TopPeriod) {
widget.TopPeriod = "day"
}
if widget.RequestUrlTemplate != "" {
if !strings.Contains(widget.RequestUrlTemplate, "{REQUEST-URL}") {
return errors.New("no `{REQUEST-URL}` placeholder specified")
@@ -47,8 +59,32 @@ func (widget *Reddit) Initialize() error {
return nil
}
func isValidRedditSortType(sortBy string) bool {
return sortBy == "hot" ||
sortBy == "new" ||
sortBy == "top" ||
sortBy == "rising"
}
func isValidRedditTopPeriod(period string) bool {
return period == "hour" ||
period == "day" ||
period == "week" ||
period == "month" ||
period == "year" ||
period == "all"
}
func (widget *Reddit) Update(ctx context.Context) {
posts, err := feed.FetchSubredditPosts(widget.Subreddit, widget.CommentsUrlTemplate, widget.RequestUrlTemplate)
// TODO: refactor, use a struct to pass all of these
posts, err := feed.FetchSubredditPosts(
widget.Subreddit,
widget.SortBy,
widget.TopPeriod,
widget.Search,
widget.CommentsUrlTemplate,
widget.RequestUrlTemplate,
)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return
@@ -58,7 +94,11 @@ func (widget *Reddit) Update(ctx context.Context) {
posts = posts[:widget.Limit]
}
posts.SortByEngagement()
if widget.ExtraSortBy == "engagement" {
posts.CalculateEngagement()
posts.SortByEngagement()
}
widget.Posts = posts
}

View File

@@ -0,0 +1,52 @@
package widget
import (
"context"
"html/template"
"time"
"github.com/glanceapp/glance/internal/assets"
"github.com/glanceapp/glance/internal/feed"
)
type Repository struct {
widgetBase `yaml:",inline"`
RequestedRepository string `yaml:"repository"`
Token OptionalEnvString `yaml:"token"`
PullRequestsLimit int `yaml:"pull-requests-limit"`
IssuesLimit int `yaml:"issues-limit"`
RepositoryDetails feed.RepositoryDetails
}
func (widget *Repository) Initialize() error {
widget.withTitle("Repository").withCacheDuration(1 * time.Hour)
if widget.PullRequestsLimit == 0 || widget.PullRequestsLimit < -1 {
widget.PullRequestsLimit = 3
}
if widget.IssuesLimit == 0 || widget.IssuesLimit < -1 {
widget.IssuesLimit = 3
}
return nil
}
func (widget *Repository) Update(ctx context.Context) {
details, err := feed.FetchRepositoryDetailsFromGithub(
widget.RequestedRepository,
string(widget.Token),
widget.PullRequestsLimit,
widget.IssuesLimit,
)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return
}
widget.RepositoryDetails = details
}
func (widget *Repository) Render() template.HTML {
return widget.render(widget, assets.RepositoryTemplate)
}

View File

@@ -10,12 +10,14 @@ import (
)
type RSS struct {
widgetBase `yaml:",inline"`
FeedRequests []feed.RSSFeedRequest `yaml:"feeds"`
Style string `yaml:"style"`
Items feed.RSSFeedItems `yaml:"-"`
Limit int `yaml:"limit"`
CollapseAfter int `yaml:"collapse-after"`
widgetBase `yaml:",inline"`
FeedRequests []feed.RSSFeedRequest `yaml:"feeds"`
Style string `yaml:"style"`
ThumbnailHeight float64 `yaml:"thumbnail-height"`
CardHeight float64 `yaml:"card-height"`
Items feed.RSSFeedItems `yaml:"-"`
Limit int `yaml:"limit"`
CollapseAfter int `yaml:"collapse-after"`
}
func (widget *RSS) Initialize() error {
@@ -29,6 +31,14 @@ func (widget *RSS) Initialize() error {
widget.CollapseAfter = 5
}
if widget.ThumbnailHeight < 0 {
widget.ThumbnailHeight = 0
}
if widget.CardHeight < 0 {
widget.CardHeight = 0
}
return nil
}
@@ -48,7 +58,11 @@ func (widget *RSS) Update(ctx context.Context) {
func (widget *RSS) Render() template.HTML {
if widget.Style == "horizontal-cards" {
return widget.render(widget, assets.RSSCardsTemplate)
return widget.render(widget, assets.RSSHorizontalCardsTemplate)
}
if widget.Style == "horizontal-cards-2" {
return widget.render(widget, assets.RSSHorizontalCards2Template)
}
return widget.render(widget, assets.RSSListTemplate)

View File

@@ -9,11 +9,12 @@ import (
"github.com/glanceapp/glance/internal/feed"
)
// TODO: rename to Markets at some point
type Stocks struct {
widgetBase `yaml:",inline"`
Stocks feed.Stocks `yaml:"-"`
Sort string `yaml:"sort-by"`
Tickers []feed.StockRequest `yaml:"stocks"`
Stocks feed.Stocks `yaml:"stocks"`
Sort string `yaml:"sort-by"`
Style string `yaml:"style"`
}
func (widget *Stocks) Initialize() error {
@@ -23,7 +24,7 @@ func (widget *Stocks) Initialize() error {
}
func (widget *Stocks) Update(ctx context.Context) {
stocks, err := feed.FetchStocksDataFromYahoo(widget.Tickers)
stocks, err := feed.FetchStocksDataFromYahoo(widget.Stocks)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return

View File

@@ -13,6 +13,7 @@ type Videos struct {
widgetBase `yaml:",inline"`
Videos feed.Videos `yaml:"-"`
VideoUrlTemplate string `yaml:"video-url-template"`
Style string `yaml:"style"`
Channels []string `yaml:"channels"`
Limit int `yaml:"limit"`
}
@@ -42,5 +43,9 @@ func (widget *Videos) Update(ctx context.Context) {
}
func (widget *Videos) Render() template.HTML {
if widget.Style == "grid-cards" {
return widget.render(widget, assets.VideosGridTemplate)
}
return widget.render(widget, assets.VideosTemplate)
}

View File

@@ -45,6 +45,8 @@ func New(widgetType string) (Widget, error) {
return &TwitchChannels{}, nil
case "lobsters":
return &Lobsters{}, nil
case "repository":
return &Repository{}, nil
default:
return nil, fmt.Errorf("unknown widget type: %s", widgetType)
}