1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

20191215 code improvements (#790)

* Upgrade godo to latest
* Fix a bunch of issues found by
* Running staticcheck on a codebase for the first time is a sobering experience
* go mod tidy
* More static improvements

Signed-off-by: Chris Cummer <chriscummer@me.com>
This commit is contained in:
Chris Cummer 2019-12-16 20:25:29 -08:00 committed by GitHub
parent e71038ccf2
commit 3a388fba23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 236 additions and 815 deletions

View File

@ -68,9 +68,16 @@ install:
## lint: runs a number of code quality checks against the source code
lint:
go vet ./...
structcheck ./...
varcheck ./...
# https://golang.org/cmd/vet/
go vet ./modules/...
# https://staticcheck.io/docs/
staticcheck ./app
staticcheck ./cfg
staticcheck ./modules/...
staticcheck ./utils
staticcheck ./view
staticcheck ./wtf
## run: executes the locally-installed version
run: build

View File

@ -1,19 +0,0 @@
package app
// This file contains the error messages that get written to the terminal when
// something goes wrong with the configuration process.
//
// As a general rule, if one of these has to be shown the app should then die
// via os.Exit(1)
import (
"fmt"
"github.com/logrusorgru/aurora"
)
/* -------------------- Unexported Functions -------------------- */
func displayError(err error) {
fmt.Printf("%s %s\n\n", aurora.Red("Error:"), err.Error())
}

View File

@ -52,7 +52,7 @@ func (val *ModuleValidator) Validate(widgets []wtf.Wtfable) {
if hasErrors {
fmt.Println()
fmt.Printf(errStr)
fmt.Println(errStr)
os.Exit(1)
}

View File

@ -29,7 +29,7 @@ func Schedule(widget wtf.Wtfable) {
return
}
case quit := <-widget.QuitChan():
if quit == true {
if quit {
timer.Stop()
return
}

View File

@ -78,8 +78,14 @@ func MakeWidget(
var widget wtf.Wtfable
moduleConfig, _ := config.Get("wtf.mods." + moduleName)
// Don' try to initialize modules that don't exist
if moduleConfig == nil {
return nil
}
// Don't try to initialize modules that aren't enabled
if enabled := moduleConfig.UBool("enabled", false); !enabled {
// Don't initialize modules that aren't enabled
return nil
}

77
app/widget_maker_test.go Normal file
View File

@ -0,0 +1,77 @@
package app
import (
"testing"
"github.com/olebedev/config"
"github.com/stretchr/testify/assert"
"github.com/wtfutil/wtf/modules/clocks"
"github.com/wtfutil/wtf/wtf"
)
const (
disabled = `
wtf:
mods:
clocks:
enabled: false
position:
top: 0
left: 0
height: 1
width: 1
refreshInterval: 30`
enabled = `
wtf:
mods:
clocks:
enabled: true
position:
top: 0
left: 0
height: 1
width: 1
refreshInterval: 30`
)
func Test_MakeWidget(t *testing.T) {
tests := []struct {
name string
moduleName string
config *config.Config
expected wtf.Wtfable
}{
{
name: "invalid module",
moduleName: "",
config: &config.Config{},
expected: nil,
},
{
name: "valid disabled module",
moduleName: "clocks",
config: func() *config.Config {
cfg, _ := config.ParseYaml(disabled)
return cfg
}(),
expected: nil,
},
{
name: "valid enabled module",
moduleName: "clocks",
config: func() *config.Config {
cfg, _ := config.ParseYaml(enabled)
return cfg
}(),
expected: &clocks.Widget{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := MakeWidget(nil, nil, tt.moduleName, tt.config)
assert.IsType(t, tt.expected, actual)
})
}
}

View File

@ -42,6 +42,7 @@ func NewWtfApp(app *tview.Application, config *config.Config, configFilePath str
})
wtfApp.app.SetInputCapture(wtfApp.keyboardIntercept)
wtfApp.widgets = MakeWidgets(wtfApp.app, wtfApp.pages, wtfApp.config)
wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config)
wtfApp.focusTracker = NewFocusTracker(wtfApp.app, wtfApp.widgets, wtfApp.config)
@ -64,11 +65,6 @@ func NewWtfApp(app *tview.Application, config *config.Config, configFilePath str
/* -------------------- Exported Functions -------------------- */
// App returns the *tview.Application instance
func (wtfApp *WtfApp) App() *tview.Application {
return wtfApp.app
}
// Start initializes the app
func (wtfApp *WtfApp) Start() {
wtfApp.scheduleWidgets()

View File

@ -58,7 +58,7 @@ func CreateFile(fileName string) (string, error) {
// Initialize takes care of settings up the initial state of WTF configuration
// It ensures necessary directories and files exist
func Initialize(hasCustom bool) {
if hasCustom == false {
if !hasCustom {
migrateOldConfig()
}
@ -67,7 +67,7 @@ func Initialize(hasCustom bool) {
createXdgConfigDir()
createWtfConfigDir()
if hasCustom == false {
if !hasCustom {
createWtfConfigFile()
chmodConfigFile()
}

View File

@ -1,14 +0,0 @@
package cfg
import (
"errors"
)
var (
errTest = errors.New("Busted")
)
func ExampleDisplayError() {
displayError(errTest)
// Output: Error: Busted
}

1
go.mod
View File

@ -50,6 +50,7 @@ require (
github.com/xanzy/go-gitlab v0.22.2
github.com/zmb3/spotify v0.0.0-20191010212056-e12fb981aacb
github.com/zorkian/go-datadog-api v2.25.0+incompatible
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
google.golang.org/api v0.14.0
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181110093347-3be5f16b70eb // indirect

6
go.sum
View File

@ -59,8 +59,6 @@ github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda h1:NyywMz59neOoVR
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/digitalocean/godo v1.22.0 h1:bVFBKXW2TlynZ9SqmlM6ZSW6UPEzFckltSIUT5NC8L4=
github.com/digitalocean/godo v1.22.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
github.com/digitalocean/godo v1.29.0 h1:KgNNU0k9SZqVgn7m8NN9iDsq0+nluHBe8HR9QE0QVmA=
github.com/digitalocean/godo v1.29.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
@ -265,6 +263,8 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -283,6 +283,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
@ -305,6 +306,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=

View File

@ -12,11 +12,6 @@ import (
"github.com/wtfutil/wtf/view"
)
var (
ok = true
started = false
)
// Widget define wtf widget to register widget later
type Widget struct {
view.BarGraph

View File

@ -7,11 +7,18 @@ import (
"os"
)
const (
defaultTitle = "Buildkite"
defaultFocusable = true
)
// PipelineSettings defines the configuration properties for a pipeline
type PipelineSettings struct {
slug string
branches []string
}
// Settings defines the configuration properties for this module
type Settings struct {
common *cfg.Common
apiKey string `help:"Your Buildkite API Token"`
@ -19,9 +26,7 @@ type Settings struct {
pipelines []PipelineSettings `help:"An array of pipelines to get data from"`
}
const defaultTitle = "Buildkite"
const defaultFocusable = true
// NewSettingsFromYAML creates a new settings instance from a YAML config block
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
@ -33,10 +38,12 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
return &settings
}
/* -------------------- Unexported Functions -------------------- */
func buildPipelineSettings(ymlConfig *config.Config) []PipelineSettings {
pipelines := []PipelineSettings{}
for slug, _ := range ymlConfig.UMap("pipelines") {
for slug := range ymlConfig.UMap("pipelines") {
branches := utils.ToStrs(ymlConfig.UList("pipelines." + slug + ".branches"))
if len(branches) == 0 {
branches = []string{"master"}

View File

@ -12,9 +12,10 @@ func (widget *Widget) display() {
}
func (widget *Widget) content() (string, string, bool) {
if ok == false {
if !ok {
return widget.CommonSettings().Title, errorText, true
}
list := &widget.summaryList
str := ""

View File

@ -131,17 +131,13 @@ func (widget *Widget) updateCurrencies() {
}
func makeRequest(currency *fromCurrency) *http.Request {
fsym := currency.name
tsyms := ""
for _, to := range currency.to {
tsyms += fmt.Sprintf("%s,", to.name)
}
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, fsym, tsyms)
request, err := http.NewRequest("GET", url, nil)
if err != nil {
}
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, currency.name, "")
request, _ := http.NewRequest("GET", url, nil)
return request
}

View File

@ -94,11 +94,11 @@ func (widget *Widget) content() (string, string, bool) {
}
articles := widget.articles
if articles == nil || len(articles) == 0 {
if len(articles) == 0 {
return title, "No stories to display", false
}
var str string
var str string
for idx, article := range articles {
row := fmt.Sprintf(
`[%s]%2d. %s [lightblue](%s)[white]`,

View File

@ -150,9 +150,7 @@ func (widget *Widget) dropletsFetch() ([]godo.Droplet, error) {
return dropletList, err
}
for _, d := range droplets {
dropletList = append(dropletList, d)
}
dropletList = append(dropletList, droplets...)
if resp.Links == nil || resp.Links.IsLastPage() {
break

View File

@ -15,7 +15,7 @@ const (
type Settings struct {
common *cfg.Common
rates map[string][]string `help:"Defines what currency rates we want to know about`
rates map[string][]string `help:"Defines what currency rates we want to know about"`
order []string
}
@ -32,11 +32,11 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
for key, value := range raw {
settings.order = append(settings.order, key)
settings.rates[key] = []string{}
switch value.(type) {
switch value := value.(type) {
case string:
settings.rates[key] = []string{value.(string)}
settings.rates[key] = []string{value}
case []interface{}:
for _, currency := range value.([]interface{}) {
for _, currency := range value {
str, ok := currency.(string)
if ok {
settings.rates[key] = append(settings.rates[key], str)

View File

@ -63,9 +63,7 @@ func (widget *Widget) Fetch(feedURLs []string) ([]*FeedItem, error) {
return nil, err
}
for _, feedItem := range feedItems {
data = append(data, feedItem)
}
data = append(data, feedItems...)
}
data = widget.sort(data)
@ -128,7 +126,7 @@ func (widget *Widget) content() (string, string, bool) {
return title, widget.err.Error(), true
}
data := widget.stories
if data == nil || len(data) == 0 {
if len(data) == 0 {
return title, "No data", false
}
var str string

View File

@ -41,7 +41,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
leagueId, err := getLeague(settings.league)
if err != nil {
widget = Widget{
err: fmt.Errorf("Unable to get the league id for provided league '%s'", settings.league),
err: fmt.Errorf("unable to get the league id for provided league '%s'", settings.league),
Client: NewClient(settings.apiKey),
settings: settings,
}
@ -80,7 +80,7 @@ func getLeague(league string) (leagueInfo, error) {
if val, ok := leagueID[league]; ok {
return val, nil
}
return l, fmt.Errorf("No such league")
return l, fmt.Errorf("no such league")
}
// GetStandings of particular league

View File

@ -52,7 +52,7 @@ func (calEvent *CalEvent) Past() bool {
return false
}
return (calEvent.Now() == false) && calEvent.Start().Before(time.Now())
return !calEvent.Now() && calEvent.Start().Before(time.Now())
}
func (calEvent *CalEvent) ResponseFor(email string) string {

View File

@ -23,6 +23,7 @@ import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/calendar/v3"
"google.golang.org/api/option"
)
/* -------------------- Exported Functions -------------------- */
@ -43,13 +44,11 @@ func (widget *Widget) Fetch() ([]*CalEvent, error) {
}
client := getClient(ctx, config)
srv, err := calendar.New(client)
srv, err := calendar.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
return nil, err
}
calendarIds, err := widget.getCalendarIdList(srv)
// Get calendar events
var events calendar.Events
@ -58,8 +57,9 @@ func (widget *Widget) Fetch() ([]*CalEvent, error) {
timezone := widget.settings.timezone
for _, calendarId := range calendarIds {
calendarEvents, err := srv.Events.List(calendarId).TimeZone(timezone).ShowDeleted(false).TimeMin(startTime).MaxResults(eventLimit).SingleEvents(true).OrderBy("startTime").Do()
calendarIDs, err := widget.getCalendarIdList(srv)
for _, calendarID := range calendarIDs {
calendarEvents, err := srv.Events.List(calendarID).TimeZone(timezone).ShowDeleted(false).TimeMin(startTime).MaxResults(eventLimit).SingleEvents(true).OrderBy("startTime").Do()
if err != nil {
break
}
@ -132,9 +132,9 @@ func (widget *Widget) authenticate() {
log.Fatalf("Unable to read secret file. %v", widget.settings.secretFile)
}
config, err := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope)
config, _ := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope)
tok := getTokenFromWeb(config)
cacheFile, err := tokenCacheFile()
cacheFile, _ := tokenCacheFile()
saveToken(cacheFile, tok)
}
@ -150,7 +150,7 @@ func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
tok, err := config.Exchange(context.Background(), code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}

View File

@ -9,21 +9,6 @@ import (
"github.com/wtfutil/wtf/utils"
)
func (widget *Widget) sortedEvents() ([]*CalEvent, []*CalEvent) {
allDayEvents := []*CalEvent{}
timedEvents := []*CalEvent{}
for _, calEvent := range widget.calEvents {
if calEvent.AllDay() {
allDayEvents = append(allDayEvents, calEvent)
} else {
timedEvents = append(timedEvents, calEvent)
}
}
return allDayEvents, timedEvents
}
func (widget *Widget) display() {
widget.Redraw(widget.content)
}
@ -183,7 +168,7 @@ func (widget *Widget) titleColor(calEvent *CalEvent) string {
strings.ToLower(calEvent.event.Summary),
)
if match == true {
if match {
color = highlightElements[1]
}
}
@ -196,7 +181,7 @@ func (widget *Widget) titleColor(calEvent *CalEvent) string {
}
func (widget *Widget) location(calEvent *CalEvent) string {
if widget.settings.withLocation == false {
if !widget.settings.withLocation {
return ""
}
@ -212,7 +197,7 @@ func (widget *Widget) location(calEvent *CalEvent) string {
}
func (widget *Widget) responseIcon(calEvent *CalEvent) string {
if widget.settings.displayResponseStatus == false {
if !widget.settings.displayResponseStatus {
return ""
}

View File

@ -54,6 +54,10 @@ var (
func apiRequest(path, apiToken string) (*http.Response, error) {
req, err := http.NewRequest("GET", apiBaseURL+path, nil)
if err != nil {
return nil, err
}
bearer := fmt.Sprintf("Bearer %s", apiToken)
req.Header.Add("Authorization", bearer)

View File

@ -97,11 +97,3 @@ func (widget *Widget) content() (string, string, bool) {
return title, str, true
}
func (widget *Widget) openMessage() {
sel := widget.GetSelected()
if sel >= 0 && widget.messages != nil && sel < len(widget.messages) {
message := &widget.messages[sel]
utils.OpenFile(message.Text)
}
}

View File

@ -1,6 +1,7 @@
package googleanalytics
import (
"context"
"fmt"
"io/ioutil"
"log"
@ -8,10 +9,10 @@ import (
"time"
"github.com/wtfutil/wtf/utils"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
gaV3 "google.golang.org/api/analytics/v3"
gaV4 "google.golang.org/api/analyticsreporting/v4"
"google.golang.org/api/option"
)
type websiteReport struct {
@ -56,12 +57,13 @@ func buildNetClient(secretPath string) *http.Client {
log.Fatalf("Unable to get config from JSON. %v", err)
}
return jwtConfig.Client(oauth2.NoContext)
return jwtConfig.Client(context.Background())
}
func makeReportServiceV3(secretPath string) (*gaV3.Service, error) {
var netClient = buildNetClient(secretPath)
svc, err := gaV3.New(netClient)
client := buildNetClient(secretPath)
svc, err := gaV3.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Failed to create v3 Google Analytics Reporting Service")
}
@ -70,8 +72,8 @@ func makeReportServiceV3(secretPath string) (*gaV3.Service, error) {
}
func makeReportServiceV4(secretPath string) (*gaV4.Service, error) {
var netClient = buildNetClient(secretPath)
svc, err := gaV4.New(netClient)
client := buildNetClient(secretPath)
svc, err := gaV4.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Failed to create v4 Google Analytics Reporting Service")
}

View File

@ -21,6 +21,7 @@ import (
"github.com/wtfutil/wtf/utils"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
sheets "google.golang.org/api/sheets/v4"
)
@ -45,7 +46,7 @@ func (widget *Widget) Fetch() ([]*sheets.ValueRange, error) {
}
client := getClient(ctx, config)
srv, err := sheets.New(client)
srv, err := sheets.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Unable to get create server. %v", err)
return nil, err
@ -97,7 +98,7 @@ func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
tok, err := config.Exchange(context.Background(), code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}

View File

@ -52,6 +52,9 @@ var (
func apiRequest(path string) (*http.Response, error) {
req, err := http.NewRequest("GET", apiEndpoint+path+".json", nil)
if err != nil {
return nil, err
}
httpClient := &http.Client{}
resp, err := httpClient.Do(req)

View File

@ -77,13 +77,12 @@ func (widget *Widget) content() (string, string, bool) {
return title, widget.err.Error(), true
}
stories := widget.stories
if stories == nil || len(stories) == 0 {
if len(widget.stories) == 0 {
return title, "No stories to display", false
}
var str string
for idx, story := range stories {
var str string
for idx, story := range widget.stories {
u, _ := url.Parse(story.URL)
row := fmt.Sprintf(

View File

@ -22,7 +22,7 @@ type hibpError struct {
func (widget *Widget) fullURL(account string, truncated bool) string {
truncStr := "false"
if truncated == true {
if truncated {
truncStr = "true"
}

View File

@ -59,11 +59,7 @@ func (sett *Settings) HasSince() bool {
}
_, err := sett.SinceDate()
if err != nil {
return false
}
return true
return err == nil
}
// SinceDate returns the "since" settings as a proper Time instance

View File

@ -21,7 +21,6 @@ type Widget struct {
view.TextWidget
language string
result string
settings *Settings
}
@ -132,7 +131,7 @@ func (widget *Widget) nbascore() (string, string, bool) {
}
}
qColor := "[white]"
if activate == true {
if activate {
qColor = "[sandybrown]"
}
allGame += fmt.Sprintf("%s%5s%v[white] %s %3s [white]vs %s%-3s %s\n", qColor, "Q", quarter, vTeam, vScore, hColor, hScore, hTeam) // Format the score and store in allgame

View File

@ -2,14 +2,14 @@ package newrelic
// AlertCondition describes what triggers an alert for a specific policy.
type AlertCondition struct {
ID int `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
Enabled bool `json:"name,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Entities []string `json:"entities,omitempty"`
ID int `json:"id,omitempty"`
Metric string `json:"metric,omitempty"`
Name string `json:"name,omitempty"`
RunbookURL string `json:"runbook_url,omitempty"`
Terms []AlertConditionTerm `json:"terms,omitempty"`
Type string `json:"type,omitempty"`
UserDefined AlertUserDefined `json:"user_defined,omitempty"`
}

View File

@ -1,91 +0,0 @@
package newrelic
type getAlertEventsTestsInput struct {
options *AlertEventOptions
data string
}
type getAlertEventsTestsOutput struct {
data []AlertEvent
err error
}
const (
testAlertEventJSON = `
{
"id": 123,
"event_type": "VIOLATION_OPEN",
"product": "APM",
"entity_type": "Application",
"entity_group_id": 1234,
"entity_id": 12,
"priority": "Warning",
"description": "Test Alert",
"timestamp": 1472355451353,
"incident_id": 23
}
`
)
var (
testAlertEvent = AlertEvent{
ID: 123,
EventType: "VIOLATION_OPEN",
Product: "APM",
EntityType: "Application",
EntityGroupID: 1234,
EntityID: 12,
Priority: "Warning",
Description: "Test Alert",
Timestamp: 1472355451353,
IncidentID: 23,
}
getAlertEventsTests = []struct {
in getAlertEventsTestsInput
out getAlertEventsTestsOutput
}{
{
getAlertEventsTestsInput{
options: nil,
data: `{"recent_events": [` + testAlertEventJSON + `]}`,
},
getAlertEventsTestsOutput{
data: []AlertEvent{
testAlertEvent,
},
err: nil,
},
},
}
alertEventOptionsStringerTests = []struct {
in *AlertEventOptions
out string
}{
{
&AlertEventOptions{},
"",
},
{
nil,
"",
},
{
&AlertEventOptions{
Filter: AlertEventFilter{
Product: "testProduct",
EntityType: "testEntityType",
EntityGroupID: 123,
EntityID: 1234,
EventType: "testEventType",
},
Page: 1,
},
"filter%5Bentity_group_id%5D=123" +
"&filter%5Bentity_id%5D=1234" +
"&filter%5Bentity_type%5D=testEntityType" +
"&filter%5Bevent_type%5D=testEventType" +
"&filter%5Bproduct%5D=testProduct" +
"&page=1",
},
}
)

View File

@ -24,7 +24,7 @@ type ApplicationDeployment struct {
Revision string `json:"revision,omitempty"`
Changelog string `json:"changelog,omitempty"`
Description string `json:"description,omitempty"`
User string `json:"user,omitemtpy"`
User string `json:"user,omitempty"`
Timestamp time.Time `json:"timestamp,omitempty"`
Links ApplicationDeploymentLinks `json:"links,omitempty"`
}

View File

@ -1,175 +0,0 @@
package newrelic
type getApplicationMetricsTestsInput struct {
id int
options *MetricsOptions
data string
}
type getApplicationMetricsTestsOutput struct {
data []Metric
err error
}
type getApplicationMetricDataTestsInput struct {
id int
Names []string
options *MetricDataOptions
data string
}
type getApplicationMetricDataTestsOutput struct {
data *MetricDataResponse
err error
}
const (
testApplicationMetricJSON = `
{
"name": "testMetric",
"values": [
"testValue1",
"testValue2"
]
}
`
)
var (
testApplicationMetric = Metric{
Name: "testMetric",
Values: []string{"testValue1", "testValue2"},
}
getApplicaitonMetricsTests = []struct {
in getApplicationMetricsTestsInput
out getApplicationMetricsTestsOutput
}{
{
getApplicationMetricsTestsInput{
id: 123,
options: nil,
data: `{"metrics": [` +
testApplicationMetricJSON + `,` +
testApplicationMetricJSON +
`]}`,
},
getApplicationMetricsTestsOutput{
data: []Metric{
testApplicationMetric,
testApplicationMetric,
},
err: nil,
},
},
}
applicationMetricOptionsStringerTests = []struct {
in *MetricsOptions
out string
}{
{
&MetricsOptions{},
"",
},
{
nil,
"",
},
{
&MetricsOptions{
Name: "testName",
Page: 5,
},
"name=testName" +
"&page=5",
},
}
applicationMetricDataOptionsStringerTests = []struct {
in *MetricDataOptions
out string
}{
{
&MetricDataOptions{},
"",
},
{
nil,
"",
},
{
&MetricDataOptions{
Names: Array{[]string{"test1", "test2"}},
Values: Array{[]string{"value1", "value2"}},
From: testTime,
To: testTime,
Period: 123,
Summarize: true,
Raw: true,
},
"from=" + testTimeStringEscaped +
"&names%5B%5D=test1" +
"&names%5B%5D=test2" +
"&period=123" +
"&raw=true" +
"&summarize=true" +
"&to=" + testTimeStringEscaped +
"&values%5B%5D=value1&values%5B%5D=value2",
},
}
testApplicationMetricDataJSON = `
{
"metric_data": {
"from": "` + testTimeRawString + `",
"to": "` + testTimeRawString + `",
"metrics_found": ["name1"],
"metrics_not_found": ["name2"],
"metrics": [
{
"name": "testName",
"timeslices": [
{
"from": "` + testTimeRawString + `",
"to": "` + testTimeRawString + `",
"values": {"testVal": 1.234}
}
]
}
]
}
}
`
testApplicationMetricData = MetricData{
Name: "testName",
Timeslices: []MetricTimeslice{
MetricTimeslice{
From: testTime,
To: testTime,
Values: map[string]float64{
"testVal": 1.234,
},
},
},
}
getApplicaitonMetricDataTests = []struct {
in getApplicationMetricDataTestsInput
out getApplicationMetricDataTestsOutput
}{
{
getApplicationMetricDataTestsInput{
id: 1234,
Names: []string{"name1", "name2"},
options: &MetricDataOptions{},
data: testApplicationMetricDataJSON,
},
getApplicationMetricDataTestsOutput{
data: &MetricDataResponse{
From: testTime,
To: testTime,
MetricsFound: []string{"name1"},
MetricsNotFound: []string{"name2"},
Metrics: []MetricData{testApplicationMetricData},
},
err: nil,
},
},
}
)

View File

@ -1,165 +0,0 @@
package newrelic
type getApplicationsTestsInput struct {
options *ApplicationOptions
data string
}
type getApplicationsTestsOutput struct {
data []Application
err error
}
type getApplicationTestsInput struct {
id int
data string
}
type getApplicationTestsOutput struct {
data *Application
err error
}
var (
testApplicationJSON = `
{
"application_summary": {
"apdex_score": 1.0,
"apdex_target": 0.5,
"error_rate": 0.0,
"host_count": 1,
"instance_count": 1,
"response_time": 0.263,
"throughput": 12.3
},
"end_user_summary": {
"response_time": 0.263,
"throughput": 12.3,
"apdex_target": 0.5,
"apdex_score": 1
},
"health_status": "green",
"id": 12345,
"language": "java",
"last_reported_at": "` + testTimeRawString + `",
"links": {
"alert_policy": 123,
"application_hosts": [
1234567
],
"application_instances": [
1234568
],
"servers": [
54321
]
},
"name": "test.example.com",
"reporting": true,
"settings": {
"app_apdex_threshold": 0.5,
"enable_real_user_monitoring": true,
"end_user_apdex_threshold": 1.0,
"use_server_side_config": false
}
}
`
testApplication = Application{
ID: 12345,
Name: "test.example.com",
Language: "java",
HealthStatus: "green",
Reporting: true,
LastReportedAt: testTime,
ApplicationSummary: ApplicationSummary{
ResponseTime: 0.263,
Throughput: 12.3,
ErrorRate: 0,
ApdexTarget: 0.5,
ApdexScore: 1,
HostCount: 1,
InstanceCount: 1,
ConcurrentInstanceCount: 0,
},
EndUserSummary: EndUserSummary{
ResponseTime: 0.263,
Throughput: 12.3,
ApdexTarget: 0.5,
ApdexScore: 1,
},
Settings: Settings{
AppApdexThreshold: 0.5,
EndUserApdexThreshold: 1,
EnableRealUserMonitoring: true,
UseServerSideConfig: false,
},
Links: Links{
Servers: []int{54321},
ApplicationHosts: []int{1234567},
ApplicationInstances: []int{1234568},
AlertPolicy: 123,
},
}
testApplications = []Application{
testApplication,
testApplication,
}
getApplicationTests = []struct {
in getApplicationTestsInput
out getApplicationTestsOutput
}{
{
getApplicationTestsInput{
id: 12345,
data: `{ "application":` + testApplicationJSON + `}`,
},
getApplicationTestsOutput{
data: &testApplication,
},
},
}
getApplicationsTests = []struct {
in getApplicationsTestsInput
out getApplicationsTestsOutput
}{
{
getApplicationsTestsInput{
options: nil,
data: `{"applications":[` + testApplicationJSON + "," + testApplicationJSON + "]}",
},
getApplicationsTestsOutput{
data: testApplications,
err: nil,
},
},
}
applicationOptionsStringerTests = []struct {
in *ApplicationOptions
out string
}{
{
&ApplicationOptions{},
"",
},
{
&ApplicationOptions{
Filter: ApplicationFilter{
Name: "testName",
Host: "testHost",
IDs: []int{123, 456},
Language: "java",
},
Page: 5,
},
`filter%5Bhost%5D=testHost` +
`&filter%5Bids%5D=123%2C456` +
`&filter%5Blanguage%5D=java` +
`&filter%5Bname%5D=testName` +
`&page=5`,
},
{
nil,
"",
},
}
)

View File

@ -1,17 +0,0 @@
package newrelic
import (
"net/url"
"time"
)
const (
testAPIKey = "test_api_key"
testTimeRawString = "2016-01-20T20:29:38Z"
)
var (
testTime, _ = time.Parse(time.RFC3339, testTimeRawString)
testTimeString = testTime.String()
testTimeStringEscaped = url.QueryEscape(testTimeString)
)

View File

@ -52,25 +52,20 @@ func (c *Client) doRequest(req *http.Request, out interface{}) error {
func encodeGetParams(params map[string]interface{}) string {
s := url.Values{}
for k, v := range params {
switch v.(type) {
switch val := v.(type) {
case string:
val := v.(string)
if val != "" {
s.Add(k, val)
}
case int:
val := v.(int)
// TODO: Zero values versus not defined
if val != 0 {
s.Add(k, strconv.Itoa(val))
}
case []string:
val := v.([]string)
if len(val) != 0 {
s.Add(k, strings.Join(val, ","))
}
case []int:
val := v.([]int)
arr := []string{}
for _, v := range val {
arr = append(arr, strconv.Itoa(v))
@ -79,19 +74,15 @@ func encodeGetParams(params map[string]interface{}) string {
s.Add(k, strings.Join(arr, ","))
}
case time.Time:
val := v.(time.Time)
if !val.IsZero() {
s.Add(k, val.String())
}
case Array:
val := v.(Array)
for _, v := range val.arr {
s.Add(k, v)
}
case bool:
if v.(bool) {
s.Add(k, "true")
}
default:
s.Add(k, fmt.Sprintf("%v", v))
}

View File

@ -1,119 +0,0 @@
package newrelic
import (
"errors"
"net/http"
"strings"
)
type testJSONInterface struct {
data string `json:"data"id,omitempty"`
}
type testParamsInterface struct {
data string
}
type doGetTestsInput struct {
path string
params *testParamsInterface
out testJSONInterface
status int
data string
}
type doGetTestsOutput struct {
data testJSONInterface
err error
}
type doRequestTestsInput struct {
req *http.Request
out testJSONInterface
status int
data string
}
type doRequestTestOutput struct {
data testJSONInterface
err error
}
var (
doGetTests = []struct {
in doGetTestsInput
out doGetTestsOutput
}{
{
doGetTestsInput{
path: "somePath",
params: &testParamsInterface{"testData"},
out: testJSONInterface{"testData"},
status: 200,
data: `{"data": "testStructData"}`,
},
doGetTestsOutput{
data: testJSONInterface{"testData"},
err: nil,
},
},
{
doGetTestsInput{
status: 404,
data: "Not Found",
},
doGetTestsOutput{
err: errors.New("newrelic http error (404 Not Found): Not Found"),
},
},
}
testRequest, _ = http.NewRequest("GET", "http://testPath",
strings.NewReader("testBody"))
doRequestTests = []struct {
in doRequestTestsInput
out doRequestTestOutput
}{
{
doRequestTestsInput{
req: testRequest,
out: testJSONInterface{"testData"},
status: 200,
data: `{"data": "testStructData"}`,
},
doRequestTestOutput{
data: testJSONInterface{"testData"},
err: nil,
},
},
}
encodeGetParamsTests = []struct {
in map[string]interface{}
out string
}{
{
map[string]interface{}{
"testInt": 5,
"testString": "test",
"testStringSlice": []string{"test1", "test2"},
"testArray": Array{[]string{"test1", "test2"}},
"testTime": testTime,
},
"testArray=test1" +
"&testArray=test2" +
"&testInt=5" +
"&testString=test" +
"&testStringSlice=test1%2Ctest2" +
"&testTime=" + testTimeStringEscaped,
},
{
map[string]interface{}{
"unexpectedType": map[string]string{"unexpected": "type"},
},
"unexpectedType=map%5Bunexpected%3Atype%5D",
},
}
)
func (m *testParamsInterface) String() string {
return "data=testData"
}

View File

@ -6,7 +6,7 @@ import (
// Usage describes usage over a single time period.
type Usage struct {
From time.Time `json"from,omitempty"`
From time.Time `json:"from,omitempty"`
To time.Time `json:"to,omitempty"`
Usage int `json:"usage,omitempty"`
}

View File

@ -34,10 +34,10 @@ var opsGenieAPIUrl = map[string]string{
func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse, error) {
agregatedResponses := []*OnCallResponse{}
if regionUrl, regionErr := opsGenieAPIUrl[widget.settings.region]; regionErr {
if regionURL, regionErr := opsGenieAPIUrl[widget.settings.region]; regionErr {
for _, sched := range schedules {
scheduleUrl := fmt.Sprintf("%s/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", regionUrl, sched, scheduleIdentifierType)
response, err := opsGenieRequest(scheduleUrl, widget.settings.apiKey)
scheduleURL := fmt.Sprintf("%s/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", regionURL, sched, scheduleIdentifierType)
response, err := opsGenieRequest(scheduleURL, widget.settings.apiKey)
agregatedResponses = append(agregatedResponses, response)
if err != nil {
return nil, err
@ -45,7 +45,7 @@ func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) (
}
return agregatedResponses, nil
} else {
return nil, fmt.Errorf("You specified wrong region. Possible options are only 'us' and 'eu'.")
return nil, fmt.Errorf("you specified wrong region. Possible options are only 'us' and 'eu'")
}
}

View File

@ -48,7 +48,7 @@ func (widget *Widget) content() (string, string, bool) {
} else {
for _, data := range onCallResponses {
if (len(data.OnCallData.Recipients) == 0) && (widget.settings.displayEmpty == false) {
if (len(data.OnCallData.Recipients) == 0) && !widget.settings.displayEmpty {
continue
}

View File

@ -26,7 +26,7 @@ func GetOnCalls(apiKey string, scheduleIDs []string) ([]pagerduty.OnCall, error)
results = append(results, oncalls.OnCalls...)
for oncalls.APIListObject.More == true {
for oncalls.APIListObject.More {
queryOpts.APIListObject.Offset = oncalls.APIListObject.Offset
oncalls, err = client.ListOnCalls(queryOpts)
if err != nil {
@ -54,7 +54,7 @@ func GetIncidents(apiKey string) ([]pagerduty.Incident, error) {
}
results = append(results, items.Incidents...)
for items.APIListObject.More == true {
for items.APIListObject.More {
queryOpts.APIListObject.Offset = items.APIListObject.Offset
items, err = client.ListIncidents(queryOpts)
if err != nil {

View File

@ -64,7 +64,6 @@ type ItemLists struct {
type request struct {
requestBody interface{}
method string
result interface{}
headers map[string]string
url string
}
@ -100,7 +99,7 @@ func (client *Client) request(req request, result interface{}) error {
}
if err := json.Unmarshal(responseBody, &result); err != nil {
return fmt.Errorf("Could not unmarshal url [%s] \n\t\tresponse [%s] request[%s] error:%w",
return fmt.Errorf("could not unmarshal url [%s] \n\t\tresponse [%s] request[%s] error:%w",
req.url, responseBody, jsonValues, err)
}
@ -120,13 +119,13 @@ func (client *Client) ObtainRequestToken() (code string, err error) {
var responseData map[string]string
req := request{
method: "POST",
url: url,
requestBody: requestData,
}
req.headers = map[string]string{
headers: map[string]string{
"X-Accept": "application/json",
"Content-Type": "application/json",
},
method: "POST",
requestBody: requestData,
url: url,
}
err = client.request(req, &responseData)

View File

@ -61,7 +61,7 @@ func (widget *Widget) Refresh() {
}
state := Unread
if widget.archivedView == true {
if widget.archivedView {
state = Read
}
response, err := widget.client.GetLinks(state)
@ -84,7 +84,7 @@ func writeMetaDataToDisk(metaData pocketMetaData) error {
fileData, err := yaml.Marshal(metaData)
if err != nil {
return fmt.Errorf("Could not write token to disk %w", err)
return fmt.Errorf("could not write token to disk %w", err)
}
wtfConfigDir, err := cfg.WtfConfigDir()
@ -187,7 +187,7 @@ func (widget *Widget) openLink() {
func (widget *Widget) toggleLink() {
sel := widget.GetSelected()
action := Archive
if widget.archivedView == true {
if widget.archivedView {
action = ReAdd
}
@ -205,7 +205,7 @@ func (widget *Widget) toggleLink() {
func (widget *Widget) formatItem(item Item, isSelected bool) string {
foreColor, backColor := widget.settings.common.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenBackground
text := item.ResolvedTitle
if isSelected == true {
if isSelected {
foreColor = widget.settings.common.Colors.RowTheme.HighlightedForeground
backColor = widget.settings.common.Colors.RowTheme.HighlightedBackground
@ -217,7 +217,7 @@ func (widget *Widget) formatItem(item Item, isSelected bool) string {
func (widget *Widget) content() (string, string, bool) {
title := widget.CommonSettings().Title
currentViewTitle := "Reading List"
if widget.archivedView == true {
if widget.archivedView {
currentViewTitle = "Archived list"
}

View File

@ -12,11 +12,6 @@ import (
"github.com/wtfutil/wtf/view"
)
var (
ok = true
started = false
)
// Widget define wtf widget to register widget later
type Widget struct {
view.BarGraph

View File

@ -18,7 +18,7 @@ func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*A
return items, err
}
err = utils.ParseJSON(&items, resp.Body)
utils.ParseJSON(&items, resp.Body)
return items, nil
}
@ -38,7 +38,7 @@ func rollbarItemRequest(accessToken, assignedToName string, activeOnly bool) (*h
}
requestURL := rollbarAPIURL.ResolveReference(&url.URL{RawQuery: params.Encode()})
req, err := http.NewRequest("GET", requestURL.String(), nil)
req, _ := http.NewRequest("GET", requestURL.String(), nil)
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")

View File

@ -61,14 +61,3 @@ func (widget *Widget) content() (string, string, bool) {
return widget.CommonSettings().Title, str, false
}
func (widget *Widget) labelColor(label string) string {
switch label {
case "on":
return "green"
case "off":
return "red"
default:
return "white"
}
}

View File

@ -128,12 +128,12 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
func (w *Widget) refreshSpotifyInfos() error {
if w.client == nil || w.playerState == nil {
return errors.New("Authentication failed! Please log in to Spotify by visiting the following page in your browser: " + authURL)
return errors.New("authentication failed! Please log in to Spotify by visiting the following page in your browser: " + authURL)
}
var err error
w.playerState, err = w.client.PlayerState()
if err != nil {
return errors.New("Extracting player state failed! Please refresh or restart WTF")
return errors.New("extracting player state failed! Please refresh or restart WTF")
}
w.Info.Album = fmt.Sprint(w.playerState.CurrentlyPlaying.Item.Album.Name)
artists := ""

View File

@ -40,7 +40,7 @@ func GetLinks(subreddit string, sortMode string, topTimePeriod string) ([]Link,
}
if len(m.Data.Children) == 0 {
return nil, fmt.Errorf("No links")
return nil, fmt.Errorf("no links")
}
var links []Link

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/alecthomas/chroma/formatters"
@ -89,10 +88,6 @@ func (widget *Widget) content() (string, string, bool) {
return title, text, widget.settings.wrapText
}
func (widget *Widget) fileName() string {
return filepath.Base(widget.CurrentSource())
}
func (widget *Widget) formattedText() string {
filePath, _ := utils.ExpandHomeDir(widget.CurrentSource())
@ -157,9 +152,7 @@ func (widget *Widget) watchForFileChanges() {
for _, source := range widget.Sources {
fullPath, err := utils.ExpandHomeDir(source)
if err == nil {
if err := watch.Add(fullPath); err != nil {
// Ignore it, don't care about a file that doesn't exist
}
watch.Add(fullPath)
}
}

View File

@ -22,14 +22,13 @@ func (widget *Widget) content() (string, string, bool) {
return title, widget.err.Error(), true
}
data := widget.torrents
if data == nil || len(data) == 0 {
if len(widget.torrents) == 0 {
return title, "No data", false
}
str := ""
for idx, torrent := range data {
for idx, torrent := range widget.torrents {
torrName := *torrent.Name
row := fmt.Sprintf(

View File

@ -45,9 +45,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
// Fetch retrieves torrent data from the Transmission daemon
func (widget *Widget) Fetch() ([]*transmissionrpc.Torrent, error) {
widget.mu.Lock()
widget.mu.Unlock()
if widget.client == nil {
return nil, errors.New("client was not initialized")
}

View File

@ -69,11 +69,11 @@ func (widget *Widget) content() (string, string, bool) {
str = widget.err.Error()
} else {
var rowFormat = "[%s] [%s] %s-%s (%s) [%s]%s - [blue]%s"
if widget.settings.compact != true {
if !widget.settings.compact {
rowFormat += "\n"
}
for idx, build := range widget.builds.Builds {
for idx, build := range widget.builds.Builds {
row := fmt.Sprintf(
rowFormat,
widget.RowColor(idx),

View File

@ -34,7 +34,7 @@ func NewClient(settings *Settings) *Client {
ClientSecret: settings.consumerSecret,
TokenURL: "https://api.twitter.com/oauth2/token",
}
httpClient = conf.Client(oauth2.NoContext)
httpClient = conf.Client(context.Background())
} else {
ctx := context.Background()
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{

View File

@ -19,7 +19,6 @@ type Widget struct {
client *Client
idx int
settings *Settings
sources []string
}
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {

View File

@ -16,7 +16,6 @@ import (
type Client struct {
httpClient *http.Client
screenNames []string
bearerToken string
}
// TwitterStats Represents a stats snapshot for a single Twitter user at a point in time
@ -48,7 +47,7 @@ func NewClient(settings *Settings) *Client {
ClientSecret: settings.consumerSecret,
TokenURL: "https://api.twitter.com/oauth2/token",
}
httpClient = conf.Client(oauth2.NoContext)
httpClient = conf.Client(context.Background())
} else {
ctx := context.Background()
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{

View File

@ -50,7 +50,7 @@ func (widget *Widget) content() (string, string, bool) {
teams := widget.teams
var str string
if teams == nil || len(teams) == 0 {
if len(teams) == 0 {
return title, "No teams specified", false
}

View File

@ -23,7 +23,6 @@ type Stations struct {
} `xml:"location"`
}
type location struct {
name string
index float32
@ -33,21 +32,21 @@ type location struct {
}
func GetLocationData(cityname string) (*location, error) {
var locdata location;
var locdata location
resp, err := apiRequest()
if err != nil {
return nil, err
}
stations, err := parseXML(resp.Body);
if(err != nil) {
stations, err := parseXML(resp.Body)
if err != nil {
return nil, err
}
for _, city := range stations.Location {
if(city.ID == cityname) {
locdata = location { name: city.ID, index: city.Index, time: city.Time, date: city.Date, status: city.Status }
break;
if city.ID == cityname {
locdata = location{name: city.ID, index: city.Index, time: city.Time, date: city.Date, status: city.Status}
break
}
}
return &locdata, err
@ -57,6 +56,9 @@ func GetLocationData(cityname string) (*location, error) {
func apiRequest() (*http.Response, error) {
req, err := http.NewRequest("GET", "https://uvdata.arpansa.gov.au/xml/uvvalues.xml", nil)
if err != nil {
return nil, err
}
httpClient := &http.Client{}
resp, err := httpClient.Do(req)
@ -74,7 +76,7 @@ func parseXML(text io.Reader) (Stations, error) {
dec := xml.NewDecoder(text)
dec.Strict = false
var v Stations;
var v Stations
err := dec.Decode(&v)
return v, err;
return v, err
}

View File

@ -15,7 +15,7 @@ func (widget *Widget) display() {
func (widget *Widget) content() (string, string, bool) {
var err string
if widget.apiKeyValid() == false {
if !widget.apiKeyValid() {
err = " Environment variable WTF_OWM_API_KEY is not set\n"
}

View File

@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
)
@ -13,12 +12,6 @@ type Resource struct {
Raw string
}
func errHandler(err error) {
if err != nil {
log.Print(err)
}
}
func (widget *Widget) api(meth string, path string, params string) (*Resource, error) {
trn := &http.Transport{}

View File

@ -63,7 +63,7 @@ func Truncate(src string, maxLen int, withEllipse bool) string {
for idx := range src {
runeCount++
if runeCount > maxLen {
if withEllipse == true {
if withEllipse {
return src[:idx-1] + "…"
}

View File

@ -92,10 +92,10 @@ func OpenFile(path string) {
if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) {
if len(OpenUrlUtil) > 0 {
commands := append(OpenUrlUtil, path)
args := commands[1:len(commands)]
exec.Command(commands[0], args...).Start()
exec.Command(commands[0], commands[1:]...).Start()
return
}
switch runtime.GOOS {
case "linux":
exec.Command("xdg-open", path).Start()

View File

@ -24,7 +24,7 @@ func Test_ASCIItoTviewColors(t *testing.T) {
},
{
name: "with defined color",
text: "[38;5;226mcat/",
text: "[38;5;226mcat/\x1b[0m",
expected: "[38;5;226mcat/[-]",
},
}