From 4c9990bafd995e9143cdf82a21cbb02810956eab Mon Sep 17 00:00:00 2001 From: Casey Primozic Date: Tue, 22 Oct 2019 11:58:20 -0700 Subject: [PATCH] Implement initial twitterstats module * Create module skeleton based off of the existing twitter module * Strip out unused pieces and try to make it as minimal as possible * Implement settings parsing, converting the untyped `screenNames` slice into an slice of strings * Implement initial minimal display, showing a table with all usernames and their follower count + # of tweets (using dummy metrics for now) --- app/widget_maker.go | 4 +++ modules/twitterstats/client.go | 48 ++++++++++++++++++++++++++ modules/twitterstats/settings.go | 39 +++++++++++++++++++++ modules/twitterstats/widget.go | 58 ++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 modules/twitterstats/client.go create mode 100644 modules/twitterstats/settings.go create mode 100644 modules/twitterstats/widget.go diff --git a/app/widget_maker.go b/app/widget_maker.go index cab1821a..17ef4b1d 100644 --- a/app/widget_maker.go +++ b/app/widget_maker.go @@ -54,6 +54,7 @@ import ( "github.com/wtfutil/wtf/modules/travisci" "github.com/wtfutil/wtf/modules/trello" "github.com/wtfutil/wtf/modules/twitter" + "github.com/wtfutil/wtf/modules/twitterstats" "github.com/wtfutil/wtf/modules/unknown" "github.com/wtfutil/wtf/modules/victorops" "github.com/wtfutil/wtf/modules/weatherservices/arpansagovau" @@ -239,6 +240,9 @@ func MakeWidget( case "twitter": settings := twitter.NewSettingsFromYAML(moduleName, moduleConfig, config) widget = twitter.NewWidget(app, pages, settings) + case "twitterstats": + settings := twitterstats.NewSettingsFromYAML(moduleName, moduleConfig, config) + widget = twitterstats.NewWidget(app, pages, settings) case "victorops": settings := victorops.NewSettingsFromYAML(moduleName, moduleConfig, config) widget = victorops.NewWidget(app, settings) diff --git a/modules/twitterstats/client.go b/modules/twitterstats/client.go new file mode 100644 index 00000000..353d3e54 --- /dev/null +++ b/modules/twitterstats/client.go @@ -0,0 +1,48 @@ +package twitterstats + +import ( + "log" +) + +type Client struct { + apiBase string + consumerKey string + consumerSecret string + accessToken string + accessTokenSecret string + screenNames []string +} + +func NewClient(settings *Settings) *Client { + usernames := make([]string, len(settings.screenNames)) + for i, username := range settings.screenNames { + switch username.(type) { + default: + { + log.Fatalf("All `screenName`s in twitterstats config must be of type string") + } + case string: + usernames[i] = username.(string) + } + + } + + client := Client{ + apiBase: "https://api.twitter.com/1.1/", + consumerKey: settings.consumerKey, + consumerSecret: settings.consumerSecret, + accessToken: settings.accessToken, + accessTokenSecret: settings.accessTokenSecret, + screenNames: usernames, + } + + return &client +} + +func (client *Client) GetFollowerCounts() []int64 { + return []int64{0, 0, 0, 0, 0} // TODO +} + +func (client *Client) GetTweetCounts() []int64 { + return []int64{0, 0, 0, 0, 0} // TODO +} diff --git a/modules/twitterstats/settings.go b/modules/twitterstats/settings.go new file mode 100644 index 00000000..9229a59d --- /dev/null +++ b/modules/twitterstats/settings.go @@ -0,0 +1,39 @@ +package twitterstats + +import ( + "os" + + "github.com/olebedev/config" + "github.com/wtfutil/wtf/cfg" +) + +const ( + defaultFocusable = true + defaultTitle = "Twitter Stats" +) + +type Settings struct { + common *cfg.Common + + consumerKey string + consumerSecret string + accessToken string + accessTokenSecret string + + screenNames []interface{} +} + +func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { + settings := Settings{ + common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), + + consumerKey: ymlConfig.UString("consumerKey", os.Getenv("WTF_TWITTER_CONSUMER_KEY")), + consumerSecret: ymlConfig.UString("consumerSecret", os.Getenv("WTF_TWITTER_CONSUMER_SECRET")), + accessToken: ymlConfig.UString("accessToken", os.Getenv("WTF_TWITTER_ACCESS_TOKEN")), + accessTokenSecret: ymlConfig.UString("accessTokenSecret", os.Getenv("WTF_TWITTER_ACCESS_TOKEN_SECRET")), + + screenNames: ymlConfig.UList("screenNames"), + } + + return &settings +} diff --git a/modules/twitterstats/widget.go b/modules/twitterstats/widget.go new file mode 100644 index 00000000..eb12f87b --- /dev/null +++ b/modules/twitterstats/widget.go @@ -0,0 +1,58 @@ +package twitterstats + +import ( + "fmt" + + "github.com/rivo/tview" + "github.com/wtfutil/wtf/view" +) + +type Widget struct { + view.KeyboardWidget + view.TextWidget + + client *Client + idx int + settings *Settings + sources []string +} + +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { + widget := Widget{ + TextWidget: view.NewTextWidget(app, settings.common), + + idx: 0, + settings: settings, + } + + widget.client = NewClient(settings) + + widget.View.SetBorderPadding(1, 1, 1, 1) + widget.View.SetWrap(true) + widget.View.SetWordWrap(true) + + return &widget +} + +func (widget *Widget) Refresh() { + widget.Redraw(widget.content) +} + +func (widget *Widget) content() (string, string, bool) { + usernames := widget.client.screenNames + followerCounts := widget.client.GetFollowerCounts() + tweetCounts := widget.client.GetTweetCounts() + + // Add header row + str := fmt.Sprintf("%-16s %-8s %-8s\n", "Username", "Followers", "# Tweets") + + // Add rows for each of the followed usernames + for i, username := range usernames { + followerCount := followerCounts[i] + tweetCount := tweetCounts[i] + + str += fmt.Sprintf("%-16s %8d %8d\n", username, followerCount, tweetCount) + } + + return "Twitter Stats", str, true +}