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:
parent
e71038ccf2
commit
3a388fba23
13
Makefile
13
Makefile
@ -68,9 +68,16 @@ install:
|
|||||||
|
|
||||||
## lint: runs a number of code quality checks against the source code
|
## lint: runs a number of code quality checks against the source code
|
||||||
lint:
|
lint:
|
||||||
go vet ./...
|
# https://golang.org/cmd/vet/
|
||||||
structcheck ./...
|
go vet ./modules/...
|
||||||
varcheck ./...
|
|
||||||
|
# https://staticcheck.io/docs/
|
||||||
|
staticcheck ./app
|
||||||
|
staticcheck ./cfg
|
||||||
|
staticcheck ./modules/...
|
||||||
|
staticcheck ./utils
|
||||||
|
staticcheck ./view
|
||||||
|
staticcheck ./wtf
|
||||||
|
|
||||||
## run: executes the locally-installed version
|
## run: executes the locally-installed version
|
||||||
run: build
|
run: build
|
||||||
|
@ -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())
|
|
||||||
}
|
|
@ -52,7 +52,7 @@ func (val *ModuleValidator) Validate(widgets []wtf.Wtfable) {
|
|||||||
|
|
||||||
if hasErrors {
|
if hasErrors {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(errStr)
|
fmt.Println(errStr)
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func Schedule(widget wtf.Wtfable) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
case quit := <-widget.QuitChan():
|
case quit := <-widget.QuitChan():
|
||||||
if quit == true {
|
if quit {
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,14 @@ func MakeWidget(
|
|||||||
var widget wtf.Wtfable
|
var widget wtf.Wtfable
|
||||||
|
|
||||||
moduleConfig, _ := config.Get("wtf.mods." + moduleName)
|
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 {
|
if enabled := moduleConfig.UBool("enabled", false); !enabled {
|
||||||
// Don't initialize modules that aren't enabled
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
app/widget_maker_test.go
Normal file
77
app/widget_maker_test.go
Normal 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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,7 @@ func NewWtfApp(app *tview.Application, config *config.Config, configFilePath str
|
|||||||
})
|
})
|
||||||
|
|
||||||
wtfApp.app.SetInputCapture(wtfApp.keyboardIntercept)
|
wtfApp.app.SetInputCapture(wtfApp.keyboardIntercept)
|
||||||
|
|
||||||
wtfApp.widgets = MakeWidgets(wtfApp.app, wtfApp.pages, wtfApp.config)
|
wtfApp.widgets = MakeWidgets(wtfApp.app, wtfApp.pages, wtfApp.config)
|
||||||
wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config)
|
wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config)
|
||||||
wtfApp.focusTracker = NewFocusTracker(wtfApp.app, 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 -------------------- */
|
/* -------------------- Exported Functions -------------------- */
|
||||||
|
|
||||||
// App returns the *tview.Application instance
|
|
||||||
func (wtfApp *WtfApp) App() *tview.Application {
|
|
||||||
return wtfApp.app
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start initializes the app
|
// Start initializes the app
|
||||||
func (wtfApp *WtfApp) Start() {
|
func (wtfApp *WtfApp) Start() {
|
||||||
wtfApp.scheduleWidgets()
|
wtfApp.scheduleWidgets()
|
||||||
|
@ -58,7 +58,7 @@ func CreateFile(fileName string) (string, error) {
|
|||||||
// Initialize takes care of settings up the initial state of WTF configuration
|
// Initialize takes care of settings up the initial state of WTF configuration
|
||||||
// It ensures necessary directories and files exist
|
// It ensures necessary directories and files exist
|
||||||
func Initialize(hasCustom bool) {
|
func Initialize(hasCustom bool) {
|
||||||
if hasCustom == false {
|
if !hasCustom {
|
||||||
migrateOldConfig()
|
migrateOldConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ func Initialize(hasCustom bool) {
|
|||||||
createXdgConfigDir()
|
createXdgConfigDir()
|
||||||
createWtfConfigDir()
|
createWtfConfigDir()
|
||||||
|
|
||||||
if hasCustom == false {
|
if !hasCustom {
|
||||||
createWtfConfigFile()
|
createWtfConfigFile()
|
||||||
chmodConfigFile()
|
chmodConfigFile()
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package cfg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
errTest = errors.New("Busted")
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleDisplayError() {
|
|
||||||
displayError(errTest)
|
|
||||||
// Output: [31mError:[0m Busted
|
|
||||||
}
|
|
1
go.mod
1
go.mod
@ -50,6 +50,7 @@ require (
|
|||||||
github.com/xanzy/go-gitlab v0.22.2
|
github.com/xanzy/go-gitlab v0.22.2
|
||||||
github.com/zmb3/spotify v0.0.0-20191010212056-e12fb981aacb
|
github.com/zmb3/spotify v0.0.0-20191010212056-e12fb981aacb
|
||||||
github.com/zorkian/go-datadog-api v2.25.0+incompatible
|
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
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||||
google.golang.org/api v0.14.0
|
google.golang.org/api v0.14.0
|
||||||
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181110093347-3be5f16b70eb // indirect
|
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181110093347-3be5f16b70eb // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -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 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 h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
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 h1:KgNNU0k9SZqVgn7m8NN9iDsq0+nluHBe8HR9QE0QVmA=
|
||||||
github.com/digitalocean/godo v1.29.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
|
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=
|
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-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 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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/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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
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-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-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-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-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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
|
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-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-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-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-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-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
|
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
|
||||||
|
@ -12,11 +12,6 @@ import (
|
|||||||
"github.com/wtfutil/wtf/view"
|
"github.com/wtfutil/wtf/view"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ok = true
|
|
||||||
started = false
|
|
||||||
)
|
|
||||||
|
|
||||||
// Widget define wtf widget to register widget later
|
// Widget define wtf widget to register widget later
|
||||||
type Widget struct {
|
type Widget struct {
|
||||||
view.BarGraph
|
view.BarGraph
|
||||||
|
@ -7,11 +7,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultTitle = "Buildkite"
|
||||||
|
defaultFocusable = true
|
||||||
|
)
|
||||||
|
|
||||||
|
// PipelineSettings defines the configuration properties for a pipeline
|
||||||
type PipelineSettings struct {
|
type PipelineSettings struct {
|
||||||
slug string
|
slug string
|
||||||
branches []string
|
branches []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Settings defines the configuration properties for this module
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
common *cfg.Common
|
common *cfg.Common
|
||||||
apiKey string `help:"Your Buildkite API Token"`
|
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"`
|
pipelines []PipelineSettings `help:"An array of pipelines to get data from"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultTitle = "Buildkite"
|
// NewSettingsFromYAML creates a new settings instance from a YAML config block
|
||||||
const defaultFocusable = true
|
|
||||||
|
|
||||||
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
|
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
|
||||||
settings := Settings{
|
settings := Settings{
|
||||||
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
|
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
|
||||||
@ -33,10 +38,12 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
|
|||||||
return &settings
|
return &settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------- Unexported Functions -------------------- */
|
||||||
|
|
||||||
func buildPipelineSettings(ymlConfig *config.Config) []PipelineSettings {
|
func buildPipelineSettings(ymlConfig *config.Config) []PipelineSettings {
|
||||||
pipelines := []PipelineSettings{}
|
pipelines := []PipelineSettings{}
|
||||||
|
|
||||||
for slug, _ := range ymlConfig.UMap("pipelines") {
|
for slug := range ymlConfig.UMap("pipelines") {
|
||||||
branches := utils.ToStrs(ymlConfig.UList("pipelines." + slug + ".branches"))
|
branches := utils.ToStrs(ymlConfig.UList("pipelines." + slug + ".branches"))
|
||||||
if len(branches) == 0 {
|
if len(branches) == 0 {
|
||||||
branches = []string{"master"}
|
branches = []string{"master"}
|
||||||
|
@ -12,9 +12,10 @@ func (widget *Widget) display() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Widget) content() (string, string, bool) {
|
func (widget *Widget) content() (string, string, bool) {
|
||||||
if ok == false {
|
if !ok {
|
||||||
return widget.CommonSettings().Title, errorText, true
|
return widget.CommonSettings().Title, errorText, true
|
||||||
}
|
}
|
||||||
|
|
||||||
list := &widget.summaryList
|
list := &widget.summaryList
|
||||||
str := ""
|
str := ""
|
||||||
|
|
||||||
|
@ -131,17 +131,13 @@ func (widget *Widget) updateCurrencies() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeRequest(currency *fromCurrency) *http.Request {
|
func makeRequest(currency *fromCurrency) *http.Request {
|
||||||
fsym := currency.name
|
|
||||||
tsyms := ""
|
tsyms := ""
|
||||||
for _, to := range currency.to {
|
for _, to := range currency.to {
|
||||||
tsyms += fmt.Sprintf("%s,", to.name)
|
tsyms += fmt.Sprintf("%s,", to.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, fsym, tsyms)
|
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, currency.name, "")
|
||||||
request, err := http.NewRequest("GET", url, nil)
|
request, _ := http.NewRequest("GET", url, nil)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
}
|
|
||||||
|
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
@ -94,11 +94,11 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
articles := widget.articles
|
articles := widget.articles
|
||||||
if articles == nil || len(articles) == 0 {
|
if len(articles) == 0 {
|
||||||
return title, "No stories to display", false
|
return title, "No stories to display", false
|
||||||
}
|
}
|
||||||
var str string
|
|
||||||
|
|
||||||
|
var str string
|
||||||
for idx, article := range articles {
|
for idx, article := range articles {
|
||||||
row := fmt.Sprintf(
|
row := fmt.Sprintf(
|
||||||
`[%s]%2d. %s [lightblue](%s)[white]`,
|
`[%s]%2d. %s [lightblue](%s)[white]`,
|
||||||
|
@ -150,9 +150,7 @@ func (widget *Widget) dropletsFetch() ([]godo.Droplet, error) {
|
|||||||
return dropletList, err
|
return dropletList, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range droplets {
|
dropletList = append(dropletList, droplets...)
|
||||||
dropletList = append(dropletList, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Links == nil || resp.Links.IsLastPage() {
|
if resp.Links == nil || resp.Links.IsLastPage() {
|
||||||
break
|
break
|
||||||
|
@ -15,7 +15,7 @@ const (
|
|||||||
type Settings struct {
|
type Settings struct {
|
||||||
common *cfg.Common
|
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
|
order []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,11 +32,11 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
|
|||||||
for key, value := range raw {
|
for key, value := range raw {
|
||||||
settings.order = append(settings.order, key)
|
settings.order = append(settings.order, key)
|
||||||
settings.rates[key] = []string{}
|
settings.rates[key] = []string{}
|
||||||
switch value.(type) {
|
switch value := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
settings.rates[key] = []string{value.(string)}
|
settings.rates[key] = []string{value}
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
for _, currency := range value.([]interface{}) {
|
for _, currency := range value {
|
||||||
str, ok := currency.(string)
|
str, ok := currency.(string)
|
||||||
if ok {
|
if ok {
|
||||||
settings.rates[key] = append(settings.rates[key], str)
|
settings.rates[key] = append(settings.rates[key], str)
|
||||||
|
@ -63,9 +63,7 @@ func (widget *Widget) Fetch(feedURLs []string) ([]*FeedItem, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, feedItem := range feedItems {
|
data = append(data, feedItems...)
|
||||||
data = append(data, feedItem)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = widget.sort(data)
|
data = widget.sort(data)
|
||||||
@ -128,7 +126,7 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
return title, widget.err.Error(), true
|
return title, widget.err.Error(), true
|
||||||
}
|
}
|
||||||
data := widget.stories
|
data := widget.stories
|
||||||
if data == nil || len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return title, "No data", false
|
return title, "No data", false
|
||||||
}
|
}
|
||||||
var str string
|
var str string
|
||||||
|
@ -41,7 +41,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
|
|||||||
leagueId, err := getLeague(settings.league)
|
leagueId, err := getLeague(settings.league)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
widget = Widget{
|
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),
|
Client: NewClient(settings.apiKey),
|
||||||
settings: settings,
|
settings: settings,
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ func getLeague(league string) (leagueInfo, error) {
|
|||||||
if val, ok := leagueID[league]; ok {
|
if val, ok := leagueID[league]; ok {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
return l, fmt.Errorf("No such league")
|
return l, fmt.Errorf("no such league")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStandings of particular league
|
// GetStandings of particular league
|
||||||
|
@ -52,7 +52,7 @@ func (calEvent *CalEvent) Past() bool {
|
|||||||
return false
|
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 {
|
func (calEvent *CalEvent) ResponseFor(email string) string {
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
"google.golang.org/api/calendar/v3"
|
"google.golang.org/api/calendar/v3"
|
||||||
|
"google.golang.org/api/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* -------------------- Exported Functions -------------------- */
|
/* -------------------- Exported Functions -------------------- */
|
||||||
@ -43,13 +44,11 @@ func (widget *Widget) Fetch() ([]*CalEvent, error) {
|
|||||||
}
|
}
|
||||||
client := getClient(ctx, config)
|
client := getClient(ctx, config)
|
||||||
|
|
||||||
srv, err := calendar.New(client)
|
srv, err := calendar.NewService(context.Background(), option.WithHTTPClient(client))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
calendarIds, err := widget.getCalendarIdList(srv)
|
|
||||||
|
|
||||||
// Get calendar events
|
// Get calendar events
|
||||||
var events calendar.Events
|
var events calendar.Events
|
||||||
|
|
||||||
@ -58,8 +57,9 @@ func (widget *Widget) Fetch() ([]*CalEvent, error) {
|
|||||||
|
|
||||||
timezone := widget.settings.timezone
|
timezone := widget.settings.timezone
|
||||||
|
|
||||||
for _, calendarId := range calendarIds {
|
calendarIDs, err := widget.getCalendarIdList(srv)
|
||||||
calendarEvents, err := srv.Events.List(calendarId).TimeZone(timezone).ShowDeleted(false).TimeMin(startTime).MaxResults(eventLimit).SingleEvents(true).OrderBy("startTime").Do()
|
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 {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -132,9 +132,9 @@ func (widget *Widget) authenticate() {
|
|||||||
log.Fatalf("Unable to read secret file. %v", widget.settings.secretFile)
|
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)
|
tok := getTokenFromWeb(config)
|
||||||
cacheFile, err := tokenCacheFile()
|
cacheFile, _ := tokenCacheFile()
|
||||||
saveToken(cacheFile, tok)
|
saveToken(cacheFile, tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
|
|||||||
log.Fatalf("Unable to read authorization code %v", err)
|
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 {
|
if err != nil {
|
||||||
log.Fatalf("Unable to retrieve token from web %v", err)
|
log.Fatalf("Unable to retrieve token from web %v", err)
|
||||||
}
|
}
|
||||||
|
@ -9,21 +9,6 @@ import (
|
|||||||
"github.com/wtfutil/wtf/utils"
|
"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() {
|
func (widget *Widget) display() {
|
||||||
widget.Redraw(widget.content)
|
widget.Redraw(widget.content)
|
||||||
}
|
}
|
||||||
@ -183,7 +168,7 @@ func (widget *Widget) titleColor(calEvent *CalEvent) string {
|
|||||||
strings.ToLower(calEvent.event.Summary),
|
strings.ToLower(calEvent.event.Summary),
|
||||||
)
|
)
|
||||||
|
|
||||||
if match == true {
|
if match {
|
||||||
color = highlightElements[1]
|
color = highlightElements[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,7 +181,7 @@ func (widget *Widget) titleColor(calEvent *CalEvent) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Widget) location(calEvent *CalEvent) string {
|
func (widget *Widget) location(calEvent *CalEvent) string {
|
||||||
if widget.settings.withLocation == false {
|
if !widget.settings.withLocation {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +197,7 @@ func (widget *Widget) location(calEvent *CalEvent) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Widget) responseIcon(calEvent *CalEvent) string {
|
func (widget *Widget) responseIcon(calEvent *CalEvent) string {
|
||||||
if widget.settings.displayResponseStatus == false {
|
if !widget.settings.displayResponseStatus {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,10 @@ var (
|
|||||||
|
|
||||||
func apiRequest(path, apiToken string) (*http.Response, error) {
|
func apiRequest(path, apiToken string) (*http.Response, error) {
|
||||||
req, err := http.NewRequest("GET", apiBaseURL+path, nil)
|
req, err := http.NewRequest("GET", apiBaseURL+path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
bearer := fmt.Sprintf("Bearer %s", apiToken)
|
bearer := fmt.Sprintf("Bearer %s", apiToken)
|
||||||
req.Header.Add("Authorization", bearer)
|
req.Header.Add("Authorization", bearer)
|
||||||
|
|
||||||
|
@ -97,11 +97,3 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
|
|
||||||
return title, str, true
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package googleanalytics
|
package googleanalytics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -8,10 +9,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/wtfutil/wtf/utils"
|
"github.com/wtfutil/wtf/utils"
|
||||||
"golang.org/x/oauth2"
|
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
gaV3 "google.golang.org/api/analytics/v3"
|
gaV3 "google.golang.org/api/analytics/v3"
|
||||||
gaV4 "google.golang.org/api/analyticsreporting/v4"
|
gaV4 "google.golang.org/api/analyticsreporting/v4"
|
||||||
|
"google.golang.org/api/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
type websiteReport struct {
|
type websiteReport struct {
|
||||||
@ -56,12 +57,13 @@ func buildNetClient(secretPath string) *http.Client {
|
|||||||
log.Fatalf("Unable to get config from JSON. %v", err)
|
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) {
|
func makeReportServiceV3(secretPath string) (*gaV3.Service, error) {
|
||||||
var netClient = buildNetClient(secretPath)
|
client := buildNetClient(secretPath)
|
||||||
svc, err := gaV3.New(netClient)
|
|
||||||
|
svc, err := gaV3.NewService(context.Background(), option.WithHTTPClient(client))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create v3 Google Analytics Reporting Service")
|
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) {
|
func makeReportServiceV4(secretPath string) (*gaV4.Service, error) {
|
||||||
var netClient = buildNetClient(secretPath)
|
client := buildNetClient(secretPath)
|
||||||
svc, err := gaV4.New(netClient)
|
svc, err := gaV4.NewService(context.Background(), option.WithHTTPClient(client))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create v4 Google Analytics Reporting Service")
|
log.Fatalf("Failed to create v4 Google Analytics Reporting Service")
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/wtfutil/wtf/utils"
|
"github.com/wtfutil/wtf/utils"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
|
"google.golang.org/api/option"
|
||||||
sheets "google.golang.org/api/sheets/v4"
|
sheets "google.golang.org/api/sheets/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ func (widget *Widget) Fetch() ([]*sheets.ValueRange, error) {
|
|||||||
}
|
}
|
||||||
client := getClient(ctx, config)
|
client := getClient(ctx, config)
|
||||||
|
|
||||||
srv, err := sheets.New(client)
|
srv, err := sheets.NewService(context.Background(), option.WithHTTPClient(client))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to get create server. %v", err)
|
log.Fatalf("Unable to get create server. %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -97,7 +98,7 @@ func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
|
|||||||
log.Fatalf("Unable to read authorization code %v", err)
|
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 {
|
if err != nil {
|
||||||
log.Fatalf("Unable to retrieve token from web %v", err)
|
log.Fatalf("Unable to retrieve token from web %v", err)
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,9 @@ var (
|
|||||||
|
|
||||||
func apiRequest(path string) (*http.Response, error) {
|
func apiRequest(path string) (*http.Response, error) {
|
||||||
req, err := http.NewRequest("GET", apiEndpoint+path+".json", nil)
|
req, err := http.NewRequest("GET", apiEndpoint+path+".json", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
|
@ -77,13 +77,12 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
return title, widget.err.Error(), true
|
return title, widget.err.Error(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
stories := widget.stories
|
if len(widget.stories) == 0 {
|
||||||
if stories == nil || len(stories) == 0 {
|
|
||||||
return title, "No stories to display", false
|
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)
|
u, _ := url.Parse(story.URL)
|
||||||
|
|
||||||
row := fmt.Sprintf(
|
row := fmt.Sprintf(
|
||||||
|
@ -22,7 +22,7 @@ type hibpError struct {
|
|||||||
|
|
||||||
func (widget *Widget) fullURL(account string, truncated bool) string {
|
func (widget *Widget) fullURL(account string, truncated bool) string {
|
||||||
truncStr := "false"
|
truncStr := "false"
|
||||||
if truncated == true {
|
if truncated {
|
||||||
truncStr = "true"
|
truncStr = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +59,7 @@ func (sett *Settings) HasSince() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err := sett.SinceDate()
|
_, err := sett.SinceDate()
|
||||||
if err != nil {
|
return err == nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SinceDate returns the "since" settings as a proper Time instance
|
// SinceDate returns the "since" settings as a proper Time instance
|
||||||
|
@ -21,7 +21,6 @@ type Widget struct {
|
|||||||
view.TextWidget
|
view.TextWidget
|
||||||
|
|
||||||
language string
|
language string
|
||||||
result string
|
|
||||||
settings *Settings
|
settings *Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +131,7 @@ func (widget *Widget) nbascore() (string, string, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
qColor := "[white]"
|
qColor := "[white]"
|
||||||
if activate == true {
|
if activate {
|
||||||
qColor = "[sandybrown]"
|
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
|
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
|
||||||
|
@ -2,14 +2,14 @@ package newrelic
|
|||||||
|
|
||||||
// AlertCondition describes what triggers an alert for a specific policy.
|
// AlertCondition describes what triggers an alert for a specific policy.
|
||||||
type AlertCondition struct {
|
type AlertCondition struct {
|
||||||
ID int `json:"id,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Enabled bool `json:"name,omitempty"`
|
|
||||||
Entities []string `json:"entities,omitempty"`
|
Entities []string `json:"entities,omitempty"`
|
||||||
|
ID int `json:"id,omitempty"`
|
||||||
Metric string `json:"metric,omitempty"`
|
Metric string `json:"metric,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
RunbookURL string `json:"runbook_url,omitempty"`
|
RunbookURL string `json:"runbook_url,omitempty"`
|
||||||
Terms []AlertConditionTerm `json:"terms,omitempty"`
|
Terms []AlertConditionTerm `json:"terms,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
UserDefined AlertUserDefined `json:"user_defined,omitempty"`
|
UserDefined AlertUserDefined `json:"user_defined,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
@ -24,7 +24,7 @@ type ApplicationDeployment struct {
|
|||||||
Revision string `json:"revision,omitempty"`
|
Revision string `json:"revision,omitempty"`
|
||||||
Changelog string `json:"changelog,omitempty"`
|
Changelog string `json:"changelog,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
User string `json:"user,omitemtpy"`
|
User string `json:"user,omitempty"`
|
||||||
Timestamp time.Time `json:"timestamp,omitempty"`
|
Timestamp time.Time `json:"timestamp,omitempty"`
|
||||||
Links ApplicationDeploymentLinks `json:"links,omitempty"`
|
Links ApplicationDeploymentLinks `json:"links,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
@ -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,
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
@ -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)
|
|
||||||
)
|
|
@ -52,25 +52,20 @@ func (c *Client) doRequest(req *http.Request, out interface{}) error {
|
|||||||
func encodeGetParams(params map[string]interface{}) string {
|
func encodeGetParams(params map[string]interface{}) string {
|
||||||
s := url.Values{}
|
s := url.Values{}
|
||||||
for k, v := range params {
|
for k, v := range params {
|
||||||
switch v.(type) {
|
switch val := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
val := v.(string)
|
|
||||||
if val != "" {
|
if val != "" {
|
||||||
s.Add(k, val)
|
s.Add(k, val)
|
||||||
}
|
}
|
||||||
case int:
|
case int:
|
||||||
val := v.(int)
|
|
||||||
// TODO: Zero values versus not defined
|
|
||||||
if val != 0 {
|
if val != 0 {
|
||||||
s.Add(k, strconv.Itoa(val))
|
s.Add(k, strconv.Itoa(val))
|
||||||
}
|
}
|
||||||
case []string:
|
case []string:
|
||||||
val := v.([]string)
|
|
||||||
if len(val) != 0 {
|
if len(val) != 0 {
|
||||||
s.Add(k, strings.Join(val, ","))
|
s.Add(k, strings.Join(val, ","))
|
||||||
}
|
}
|
||||||
case []int:
|
case []int:
|
||||||
val := v.([]int)
|
|
||||||
arr := []string{}
|
arr := []string{}
|
||||||
for _, v := range val {
|
for _, v := range val {
|
||||||
arr = append(arr, strconv.Itoa(v))
|
arr = append(arr, strconv.Itoa(v))
|
||||||
@ -79,19 +74,15 @@ func encodeGetParams(params map[string]interface{}) string {
|
|||||||
s.Add(k, strings.Join(arr, ","))
|
s.Add(k, strings.Join(arr, ","))
|
||||||
}
|
}
|
||||||
case time.Time:
|
case time.Time:
|
||||||
val := v.(time.Time)
|
|
||||||
if !val.IsZero() {
|
if !val.IsZero() {
|
||||||
s.Add(k, val.String())
|
s.Add(k, val.String())
|
||||||
}
|
}
|
||||||
case Array:
|
case Array:
|
||||||
val := v.(Array)
|
|
||||||
for _, v := range val.arr {
|
for _, v := range val.arr {
|
||||||
s.Add(k, v)
|
s.Add(k, v)
|
||||||
}
|
}
|
||||||
case bool:
|
case bool:
|
||||||
if v.(bool) {
|
s.Add(k, "true")
|
||||||
s.Add(k, "true")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
s.Add(k, fmt.Sprintf("%v", v))
|
s.Add(k, fmt.Sprintf("%v", v))
|
||||||
}
|
}
|
||||||
|
@ -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"
|
|
||||||
}
|
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
// Usage describes usage over a single time period.
|
// Usage describes usage over a single time period.
|
||||||
type Usage struct {
|
type Usage struct {
|
||||||
From time.Time `json"from,omitempty"`
|
From time.Time `json:"from,omitempty"`
|
||||||
To time.Time `json:"to,omitempty"`
|
To time.Time `json:"to,omitempty"`
|
||||||
Usage int `json:"usage,omitempty"`
|
Usage int `json:"usage,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,10 @@ var opsGenieAPIUrl = map[string]string{
|
|||||||
func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse, error) {
|
func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse, error) {
|
||||||
agregatedResponses := []*OnCallResponse{}
|
agregatedResponses := []*OnCallResponse{}
|
||||||
|
|
||||||
if regionUrl, regionErr := opsGenieAPIUrl[widget.settings.region]; regionErr {
|
if regionURL, regionErr := opsGenieAPIUrl[widget.settings.region]; regionErr {
|
||||||
for _, sched := range schedules {
|
for _, sched := range schedules {
|
||||||
scheduleUrl := fmt.Sprintf("%s/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", regionUrl, sched, scheduleIdentifierType)
|
scheduleURL := fmt.Sprintf("%s/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", regionURL, sched, scheduleIdentifierType)
|
||||||
response, err := opsGenieRequest(scheduleUrl, widget.settings.apiKey)
|
response, err := opsGenieRequest(scheduleURL, widget.settings.apiKey)
|
||||||
agregatedResponses = append(agregatedResponses, response)
|
agregatedResponses = append(agregatedResponses, response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -45,7 +45,7 @@ func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) (
|
|||||||
}
|
}
|
||||||
return agregatedResponses, nil
|
return agregatedResponses, nil
|
||||||
} else {
|
} 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'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
for _, data := range onCallResponses {
|
for _, data := range onCallResponses {
|
||||||
if (len(data.OnCallData.Recipients) == 0) && (widget.settings.displayEmpty == false) {
|
if (len(data.OnCallData.Recipients) == 0) && !widget.settings.displayEmpty {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ func GetOnCalls(apiKey string, scheduleIDs []string) ([]pagerduty.OnCall, error)
|
|||||||
|
|
||||||
results = append(results, oncalls.OnCalls...)
|
results = append(results, oncalls.OnCalls...)
|
||||||
|
|
||||||
for oncalls.APIListObject.More == true {
|
for oncalls.APIListObject.More {
|
||||||
queryOpts.APIListObject.Offset = oncalls.APIListObject.Offset
|
queryOpts.APIListObject.Offset = oncalls.APIListObject.Offset
|
||||||
oncalls, err = client.ListOnCalls(queryOpts)
|
oncalls, err = client.ListOnCalls(queryOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -54,7 +54,7 @@ func GetIncidents(apiKey string) ([]pagerduty.Incident, error) {
|
|||||||
}
|
}
|
||||||
results = append(results, items.Incidents...)
|
results = append(results, items.Incidents...)
|
||||||
|
|
||||||
for items.APIListObject.More == true {
|
for items.APIListObject.More {
|
||||||
queryOpts.APIListObject.Offset = items.APIListObject.Offset
|
queryOpts.APIListObject.Offset = items.APIListObject.Offset
|
||||||
items, err = client.ListIncidents(queryOpts)
|
items, err = client.ListIncidents(queryOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -64,7 +64,6 @@ type ItemLists struct {
|
|||||||
type request struct {
|
type request struct {
|
||||||
requestBody interface{}
|
requestBody interface{}
|
||||||
method string
|
method string
|
||||||
result interface{}
|
|
||||||
headers map[string]string
|
headers map[string]string
|
||||||
url string
|
url string
|
||||||
}
|
}
|
||||||
@ -100,8 +99,8 @@ func (client *Client) request(req request, result interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(responseBody, &result); err != nil {
|
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)
|
req.url, responseBody, jsonValues, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -120,13 +119,13 @@ func (client *Client) ObtainRequestToken() (code string, err error) {
|
|||||||
|
|
||||||
var responseData map[string]string
|
var responseData map[string]string
|
||||||
req := request{
|
req := request{
|
||||||
|
headers: map[string]string{
|
||||||
|
"X-Accept": "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: url,
|
|
||||||
requestBody: requestData,
|
requestBody: requestData,
|
||||||
}
|
url: url,
|
||||||
req.headers = map[string]string{
|
|
||||||
"X-Accept": "application/json",
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}
|
}
|
||||||
err = client.request(req, &responseData)
|
err = client.request(req, &responseData)
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func (widget *Widget) Refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state := Unread
|
state := Unread
|
||||||
if widget.archivedView == true {
|
if widget.archivedView {
|
||||||
state = Read
|
state = Read
|
||||||
}
|
}
|
||||||
response, err := widget.client.GetLinks(state)
|
response, err := widget.client.GetLinks(state)
|
||||||
@ -84,7 +84,7 @@ func writeMetaDataToDisk(metaData pocketMetaData) error {
|
|||||||
|
|
||||||
fileData, err := yaml.Marshal(metaData)
|
fileData, err := yaml.Marshal(metaData)
|
||||||
if err != nil {
|
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()
|
wtfConfigDir, err := cfg.WtfConfigDir()
|
||||||
@ -187,7 +187,7 @@ func (widget *Widget) openLink() {
|
|||||||
func (widget *Widget) toggleLink() {
|
func (widget *Widget) toggleLink() {
|
||||||
sel := widget.GetSelected()
|
sel := widget.GetSelected()
|
||||||
action := Archive
|
action := Archive
|
||||||
if widget.archivedView == true {
|
if widget.archivedView {
|
||||||
action = ReAdd
|
action = ReAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ func (widget *Widget) toggleLink() {
|
|||||||
func (widget *Widget) formatItem(item Item, isSelected bool) string {
|
func (widget *Widget) formatItem(item Item, isSelected bool) string {
|
||||||
foreColor, backColor := widget.settings.common.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenBackground
|
foreColor, backColor := widget.settings.common.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenBackground
|
||||||
text := item.ResolvedTitle
|
text := item.ResolvedTitle
|
||||||
if isSelected == true {
|
if isSelected {
|
||||||
foreColor = widget.settings.common.Colors.RowTheme.HighlightedForeground
|
foreColor = widget.settings.common.Colors.RowTheme.HighlightedForeground
|
||||||
backColor = widget.settings.common.Colors.RowTheme.HighlightedBackground
|
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) {
|
func (widget *Widget) content() (string, string, bool) {
|
||||||
title := widget.CommonSettings().Title
|
title := widget.CommonSettings().Title
|
||||||
currentViewTitle := "Reading List"
|
currentViewTitle := "Reading List"
|
||||||
if widget.archivedView == true {
|
if widget.archivedView {
|
||||||
currentViewTitle = "Archived list"
|
currentViewTitle = "Archived list"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,11 +12,6 @@ import (
|
|||||||
"github.com/wtfutil/wtf/view"
|
"github.com/wtfutil/wtf/view"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ok = true
|
|
||||||
started = false
|
|
||||||
)
|
|
||||||
|
|
||||||
// Widget define wtf widget to register widget later
|
// Widget define wtf widget to register widget later
|
||||||
type Widget struct {
|
type Widget struct {
|
||||||
view.BarGraph
|
view.BarGraph
|
||||||
|
@ -18,7 +18,7 @@ func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*A
|
|||||||
return items, err
|
return items, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utils.ParseJSON(&items, resp.Body)
|
utils.ParseJSON(&items, resp.Body)
|
||||||
|
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ func rollbarItemRequest(accessToken, assignedToName string, activeOnly bool) (*h
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestURL := rollbarAPIURL.ResolveReference(&url.URL{RawQuery: params.Encode()})
|
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("Accept", "application/json")
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
@ -61,14 +61,3 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
|
|
||||||
return widget.CommonSettings().Title, str, false
|
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -128,12 +128,12 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
|
|||||||
|
|
||||||
func (w *Widget) refreshSpotifyInfos() error {
|
func (w *Widget) refreshSpotifyInfos() error {
|
||||||
if w.client == nil || w.playerState == nil {
|
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
|
var err error
|
||||||
w.playerState, err = w.client.PlayerState()
|
w.playerState, err = w.client.PlayerState()
|
||||||
if err != nil {
|
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)
|
w.Info.Album = fmt.Sprint(w.playerState.CurrentlyPlaying.Item.Album.Name)
|
||||||
artists := ""
|
artists := ""
|
||||||
|
@ -40,7 +40,7 @@ func GetLinks(subreddit string, sortMode string, topTimePeriod string) ([]Link,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(m.Data.Children) == 0 {
|
if len(m.Data.Children) == 0 {
|
||||||
return nil, fmt.Errorf("No links")
|
return nil, fmt.Errorf("no links")
|
||||||
}
|
}
|
||||||
|
|
||||||
var links []Link
|
var links []Link
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alecthomas/chroma/formatters"
|
"github.com/alecthomas/chroma/formatters"
|
||||||
@ -89,10 +88,6 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
return title, text, widget.settings.wrapText
|
return title, text, widget.settings.wrapText
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Widget) fileName() string {
|
|
||||||
return filepath.Base(widget.CurrentSource())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (widget *Widget) formattedText() string {
|
func (widget *Widget) formattedText() string {
|
||||||
filePath, _ := utils.ExpandHomeDir(widget.CurrentSource())
|
filePath, _ := utils.ExpandHomeDir(widget.CurrentSource())
|
||||||
|
|
||||||
@ -157,9 +152,7 @@ func (widget *Widget) watchForFileChanges() {
|
|||||||
for _, source := range widget.Sources {
|
for _, source := range widget.Sources {
|
||||||
fullPath, err := utils.ExpandHomeDir(source)
|
fullPath, err := utils.ExpandHomeDir(source)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err := watch.Add(fullPath); err != nil {
|
watch.Add(fullPath)
|
||||||
// Ignore it, don't care about a file that doesn't exist
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,13 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
return title, widget.err.Error(), true
|
return title, widget.err.Error(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
data := widget.torrents
|
if len(widget.torrents) == 0 {
|
||||||
if data == nil || len(data) == 0 {
|
|
||||||
return title, "No data", false
|
return title, "No data", false
|
||||||
}
|
}
|
||||||
|
|
||||||
str := ""
|
str := ""
|
||||||
|
|
||||||
for idx, torrent := range data {
|
for idx, torrent := range widget.torrents {
|
||||||
torrName := *torrent.Name
|
torrName := *torrent.Name
|
||||||
|
|
||||||
row := fmt.Sprintf(
|
row := fmt.Sprintf(
|
||||||
|
@ -45,9 +45,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *
|
|||||||
|
|
||||||
// Fetch retrieves torrent data from the Transmission daemon
|
// Fetch retrieves torrent data from the Transmission daemon
|
||||||
func (widget *Widget) Fetch() ([]*transmissionrpc.Torrent, error) {
|
func (widget *Widget) Fetch() ([]*transmissionrpc.Torrent, error) {
|
||||||
widget.mu.Lock()
|
|
||||||
widget.mu.Unlock()
|
|
||||||
|
|
||||||
if widget.client == nil {
|
if widget.client == nil {
|
||||||
return nil, errors.New("client was not initialized")
|
return nil, errors.New("client was not initialized")
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,11 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
str = widget.err.Error()
|
str = widget.err.Error()
|
||||||
} else {
|
} else {
|
||||||
var rowFormat = "[%s] [%s] %s-%s (%s) [%s]%s - [blue]%s"
|
var rowFormat = "[%s] [%s] %s-%s (%s) [%s]%s - [blue]%s"
|
||||||
if widget.settings.compact != true {
|
if !widget.settings.compact {
|
||||||
rowFormat += "\n"
|
rowFormat += "\n"
|
||||||
}
|
}
|
||||||
for idx, build := range widget.builds.Builds {
|
|
||||||
|
|
||||||
|
for idx, build := range widget.builds.Builds {
|
||||||
row := fmt.Sprintf(
|
row := fmt.Sprintf(
|
||||||
rowFormat,
|
rowFormat,
|
||||||
widget.RowColor(idx),
|
widget.RowColor(idx),
|
||||||
|
@ -34,7 +34,7 @@ func NewClient(settings *Settings) *Client {
|
|||||||
ClientSecret: settings.consumerSecret,
|
ClientSecret: settings.consumerSecret,
|
||||||
TokenURL: "https://api.twitter.com/oauth2/token",
|
TokenURL: "https://api.twitter.com/oauth2/token",
|
||||||
}
|
}
|
||||||
httpClient = conf.Client(oauth2.NoContext)
|
httpClient = conf.Client(context.Background())
|
||||||
} else {
|
} else {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
|
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
|
||||||
|
@ -19,7 +19,6 @@ type Widget struct {
|
|||||||
client *Client
|
client *Client
|
||||||
idx int
|
idx int
|
||||||
settings *Settings
|
settings *Settings
|
||||||
sources []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
|
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
screenNames []string
|
screenNames []string
|
||||||
bearerToken string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TwitterStats Represents a stats snapshot for a single Twitter user at a point in time
|
// 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,
|
ClientSecret: settings.consumerSecret,
|
||||||
TokenURL: "https://api.twitter.com/oauth2/token",
|
TokenURL: "https://api.twitter.com/oauth2/token",
|
||||||
}
|
}
|
||||||
httpClient = conf.Client(oauth2.NoContext)
|
httpClient = conf.Client(context.Background())
|
||||||
} else {
|
} else {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
|
httpClient = oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
|
||||||
|
@ -50,7 +50,7 @@ func (widget *Widget) content() (string, string, bool) {
|
|||||||
teams := widget.teams
|
teams := widget.teams
|
||||||
var str string
|
var str string
|
||||||
|
|
||||||
if teams == nil || len(teams) == 0 {
|
if len(teams) == 0 {
|
||||||
return title, "No teams specified", false
|
return title, "No teams specified", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,43 +11,42 @@ type Stations struct {
|
|||||||
XMLName xml.Name `xml:"stations"`
|
XMLName xml.Name `xml:"stations"`
|
||||||
Text string `xml:",chardata"`
|
Text string `xml:",chardata"`
|
||||||
Location []struct {
|
Location []struct {
|
||||||
Text string `xml:",chardata"`
|
Text string `xml:",chardata"`
|
||||||
ID string `xml:"id,attr"`
|
ID string `xml:"id,attr"`
|
||||||
Name string `xml:"name"` // adl, ali, bri, can, cas, ...
|
Name string `xml:"name"` // adl, ali, bri, can, cas, ...
|
||||||
Index float32 `xml:"index"` // 0.0, 0.0, 0.0, 0.0, 0.0, ...
|
Index float32 `xml:"index"` // 0.0, 0.0, 0.0, 0.0, 0.0, ...
|
||||||
Time string `xml:"time"` // 7:24 PM, 7:24 PM, 7:54 PM...
|
Time string `xml:"time"` // 7:24 PM, 7:24 PM, 7:54 PM...
|
||||||
Date string `xml:"date"` // 29/08/2019, 29/08/2019, 2...
|
Date string `xml:"date"` // 29/08/2019, 29/08/2019, 2...
|
||||||
Fulldate string `xml:"fulldate"` // Thursday, 29 August 2019,...
|
Fulldate string `xml:"fulldate"` // Thursday, 29 August 2019,...
|
||||||
Utcdatetime string `xml:"utcdatetime"` // 2019/08/29 09:54, 2019/08...
|
Utcdatetime string `xml:"utcdatetime"` // 2019/08/29 09:54, 2019/08...
|
||||||
Status string `xml:"status"` // ok, ok, ok, ok, ok, ok, o...
|
Status string `xml:"status"` // ok, ok, ok, ok, ok, ok, o...
|
||||||
} `xml:"location"`
|
} `xml:"location"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type location struct {
|
type location struct {
|
||||||
name string
|
name string
|
||||||
index float32
|
index float32
|
||||||
time string
|
time string
|
||||||
date string
|
date string
|
||||||
status string
|
status string
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLocationData(cityname string) (*location, error) {
|
func GetLocationData(cityname string) (*location, error) {
|
||||||
var locdata location;
|
var locdata location
|
||||||
resp, err := apiRequest()
|
resp, err := apiRequest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
stations, err := parseXML(resp.Body);
|
stations, err := parseXML(resp.Body)
|
||||||
if(err != nil) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, city := range stations.Location {
|
for _, city := range stations.Location {
|
||||||
if(city.ID == cityname) {
|
if city.ID == cityname {
|
||||||
locdata = location { name: city.ID, index: city.Index, time: city.Time, date: city.Date, status: city.Status }
|
locdata = location{name: city.ID, index: city.Index, time: city.Time, date: city.Date, status: city.Status}
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &locdata, err
|
return &locdata, err
|
||||||
@ -57,6 +56,9 @@ func GetLocationData(cityname string) (*location, error) {
|
|||||||
|
|
||||||
func apiRequest() (*http.Response, error) {
|
func apiRequest() (*http.Response, error) {
|
||||||
req, err := http.NewRequest("GET", "https://uvdata.arpansa.gov.au/xml/uvvalues.xml", nil)
|
req, err := http.NewRequest("GET", "https://uvdata.arpansa.gov.au/xml/uvvalues.xml", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
@ -74,7 +76,7 @@ func parseXML(text io.Reader) (Stations, error) {
|
|||||||
dec := xml.NewDecoder(text)
|
dec := xml.NewDecoder(text)
|
||||||
dec.Strict = false
|
dec.Strict = false
|
||||||
|
|
||||||
var v Stations;
|
var v Stations
|
||||||
err := dec.Decode(&v)
|
err := dec.Decode(&v)
|
||||||
return v, err;
|
return v, err
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ func (widget *Widget) display() {
|
|||||||
func (widget *Widget) content() (string, string, bool) {
|
func (widget *Widget) content() (string, string, bool) {
|
||||||
var err string
|
var err string
|
||||||
|
|
||||||
if widget.apiKeyValid() == false {
|
if !widget.apiKeyValid() {
|
||||||
err = " Environment variable WTF_OWM_API_KEY is not set\n"
|
err = " Environment variable WTF_OWM_API_KEY is not set\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,12 +12,6 @@ type Resource struct {
|
|||||||
Raw string
|
Raw string
|
||||||
}
|
}
|
||||||
|
|
||||||
func errHandler(err error) {
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (widget *Widget) api(meth string, path string, params string) (*Resource, error) {
|
func (widget *Widget) api(meth string, path string, params string) (*Resource, error) {
|
||||||
trn := &http.Transport{}
|
trn := &http.Transport{}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func Truncate(src string, maxLen int, withEllipse bool) string {
|
|||||||
for idx := range src {
|
for idx := range src {
|
||||||
runeCount++
|
runeCount++
|
||||||
if runeCount > maxLen {
|
if runeCount > maxLen {
|
||||||
if withEllipse == true {
|
if withEllipse {
|
||||||
return src[:idx-1] + "…"
|
return src[:idx-1] + "…"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ func OpenFile(path string) {
|
|||||||
if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) {
|
if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) {
|
||||||
if len(OpenUrlUtil) > 0 {
|
if len(OpenUrlUtil) > 0 {
|
||||||
commands := append(OpenUrlUtil, path)
|
commands := append(OpenUrlUtil, path)
|
||||||
args := commands[1:len(commands)]
|
exec.Command(commands[0], commands[1:]...).Start()
|
||||||
exec.Command(commands[0], args...).Start()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux":
|
case "linux":
|
||||||
exec.Command("xdg-open", path).Start()
|
exec.Command("xdg-open", path).Start()
|
||||||
|
@ -23,8 +23,8 @@ func Test_ASCIItoTviewColors(t *testing.T) {
|
|||||||
expected: "cat",
|
expected: "cat",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with defined color",
|
name: "with defined color",
|
||||||
text: "[38;5;226mcat/[0m",
|
text: "[38;5;226mcat/\x1b[0m",
|
||||||
expected: "[38;5;226mcat/[-]",
|
expected: "[38;5;226mcat/[-]",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user