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

Merge pull request #402 from wtfutil/WTF-400-widget-configs

WTF-400 Extracting config out of modules
This commit is contained in:
Chris Cummer 2019-04-21 21:20:01 -07:00 committed by GitHub
commit 25a21f75c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
137 changed files with 2905 additions and 1099 deletions

1
.gitignore vendored
View File

@ -19,6 +19,7 @@ gcal/client_secret.json
gspreadsheets/client_secret.json gspreadsheets/client_secret.json
profile.pdf profile.pdf
report.* report.*
.vscode
# All things node # All things node
node_modules/ node_modules/

91
cfg/common_settings.go Normal file
View File

@ -0,0 +1,91 @@
package cfg
import (
"github.com/olebedev/config"
)
type Colors struct {
Background string
BorderFocusable string
BorderFocused string
BorderNormal string
Checked string
HighlightFore string
HighlightBack string
Text string
Title string
}
type Module struct {
ConfigKey string
Name string
}
type Position struct {
Height int
Left int
Top int
Width int
}
type Sigils struct {
CheckedIcon string
UncheckedIcon string
}
type Common struct {
Colors
Module
Position
Sigils
Enabled bool
FocusChar int
RefreshInterval int
Title string
}
func NewCommonSettingsFromYAML(name, configKey string, ymlConfig *config.Config) *Common {
colorsPath := "wtf.colors"
modulePath := "wtf.mods." + configKey
positionPath := "wtf.mods." + configKey + ".position"
sigilsPath := "wtf.sigils"
common := Common{
Colors: Colors{
Background: ymlConfig.UString(modulePath+".colors.background", ymlConfig.UString(colorsPath+".background", "black")),
BorderFocusable: ymlConfig.UString(colorsPath+".border.focusable", "red"),
BorderFocused: ymlConfig.UString(colorsPath+".border.focused", "orange"),
BorderNormal: ymlConfig.UString(colorsPath+".border.normal", "gray"),
Checked: ymlConfig.UString(colorsPath+".checked", "white"),
HighlightFore: ymlConfig.UString(colorsPath+".highlight.fore", "black"),
HighlightBack: ymlConfig.UString(colorsPath+".highlight.back", "green"),
Text: ymlConfig.UString(modulePath+".colors.text", ymlConfig.UString(colorsPath+".text", "white")),
Title: ymlConfig.UString(modulePath+".colors.title", ymlConfig.UString(colorsPath+".title", "white")),
},
Module: Module{
ConfigKey: configKey,
Name: name,
},
Position: Position{
Height: ymlConfig.UInt(positionPath + ".height"),
Left: ymlConfig.UInt(positionPath + ".left"),
Top: ymlConfig.UInt(positionPath + ".top"),
Width: ymlConfig.UInt(positionPath + ".width"),
},
Sigils: Sigils{
CheckedIcon: ymlConfig.UString(sigilsPath+".checkedIcon", "x"),
UncheckedIcon: ymlConfig.UString(sigilsPath+".uncheckedIcon", " "),
},
Enabled: ymlConfig.UBool(modulePath+".enabled", false),
FocusChar: ymlConfig.UInt(modulePath+".focusChar", -1),
RefreshInterval: ymlConfig.UInt(modulePath+".refreshInterval", 300),
Title: ymlConfig.UString(modulePath+".title", name),
}
return &common
}

View File

@ -1,13 +1,14 @@
package cfg package cfg
import ( import (
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"os/user"
"path/filepath"
"github.com/olebedev/config" "github.com/olebedev/config"
"github.com/wtfutil/wtf/logger"
"github.com/wtfutil/wtf/wtf"
) )
// ConfigDirV1 defines the path to the first version of configuration. Do not use this // ConfigDirV1 defines the path to the first version of configuration. Do not use this
@ -21,8 +22,8 @@ const ConfigDirV2 = "~/.config/wtf/"
// MigrateOldConfig copies any existing configuration from the old location // MigrateOldConfig copies any existing configuration from the old location
// to the new, XDG-compatible location // to the new, XDG-compatible location
func MigrateOldConfig() { func MigrateOldConfig() {
srcDir, _ := wtf.ExpandHomeDir(ConfigDirV1) srcDir, _ := expandHomeDir(ConfigDirV1)
destDir, _ := wtf.ExpandHomeDir(ConfigDirV2) destDir, _ := expandHomeDir(ConfigDirV2)
// If the old config directory doesn't exist, do not move // If the old config directory doesn't exist, do not move
if _, err := os.Stat(srcDir); os.IsNotExist(err) { if _, err := os.Stat(srcDir); os.IsNotExist(err) {
@ -38,15 +39,13 @@ func MigrateOldConfig() {
err := Copy(srcDir, destDir) err := Copy(srcDir, destDir)
if err != nil { if err != nil {
panic(err) panic(err)
} else {
logger.Log(fmt.Sprintf("Copied old config from %s to %s", srcDir, destDir))
} }
// Delete the old directory if the new one exists // Delete the old directory if the new one exists
if _, err := os.Stat(destDir); err == nil { if _, err := os.Stat(destDir); err == nil {
err := os.RemoveAll(srcDir) err := os.RemoveAll(srcDir)
if err != nil { if err != nil {
logger.Log(err.Error()) fmt.Println(err)
} }
} }
} }
@ -55,7 +54,7 @@ func MigrateOldConfig() {
// ConfigDir returns the absolute path to the configuration directory // ConfigDir returns the absolute path to the configuration directory
func ConfigDir() (string, error) { func ConfigDir() (string, error) {
configDir, err := wtf.ExpandHomeDir(ConfigDirV2) configDir, err := expandHomeDir(ConfigDirV2)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -123,7 +122,7 @@ func CreateFile(fileName string) (string, error) {
// LoadConfigFile loads the config.yml file to configure the app // LoadConfigFile loads the config.yml file to configure the app
func LoadConfigFile(filePath string) *config.Config { func LoadConfigFile(filePath string) *config.Config {
absPath, _ := wtf.ExpandHomeDir(filePath) absPath, _ := expandHomeDir(filePath)
cfg, err := config.ParseYamlFile(absPath) cfg, err := config.ParseYamlFile(absPath)
if err != nil { if err != nil {
@ -199,3 +198,43 @@ const simpleConfig = `wtf:
width: 1 width: 1
refreshInterval: 30 refreshInterval: 30
` `
/* -------------------- Unexported Functions -------------------- */
// Expand expands the path to include the home directory if the path
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
// returned as-is.
func expandHomeDir(path string) (string, error) {
if len(path) == 0 {
return path, nil
}
if path[0] != '~' {
return path, nil
}
if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
return "", errors.New("cannot expand user-specific home dir")
}
dir, err := home()
if err != nil {
return "", err
}
return filepath.Join(dir, path[1:]), nil
}
// Dir returns the home directory for the executing user.
// An error is returned if a home directory cannot be detected.
func home() (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", err
}
if currentUser.HomeDir == "" {
return "", errors.New("cannot find user-specific home dir")
}
return currentUser.HomeDir, nil
}

View File

@ -3,14 +3,18 @@ package checklist
// Checklist is a module for creating generic checklist implementations // Checklist is a module for creating generic checklist implementations
// See 'Todo' for an implementation example // See 'Todo' for an implementation example
type Checklist struct { type Checklist struct {
Selected int
Items []*ChecklistItem Items []*ChecklistItem
checkedIcon string
selected int
uncheckedIcon string
} }
func NewChecklist() Checklist { func NewChecklist(checkedIcon, uncheckedIcon string) Checklist {
list := Checklist{ list := Checklist{
Selected: -1, checkedIcon: checkedIcon,
selected: -1,
uncheckedIcon: uncheckedIcon,
} }
return list return list
@ -20,12 +24,14 @@ func NewChecklist() Checklist {
// Add creates a new item in the checklist // Add creates a new item in the checklist
func (list *Checklist) Add(checked bool, text string) { func (list *Checklist) Add(checked bool, text string) {
item := ChecklistItem{ item := NewChecklistItem(
Checked: checked, checked,
Text: text, text,
} list.checkedIcon,
list.uncheckedIcon,
)
list.Items = append([]*ChecklistItem{&item}, list.Items...) list.Items = append([]*ChecklistItem{item}, list.Items...)
} }
// CheckedItems returns a slice of all the checked items // CheckedItems returns a slice of all the checked items
@ -43,7 +49,7 @@ func (list *Checklist) CheckedItems() []*ChecklistItem {
// Delete removes the selected item from the checklist // Delete removes the selected item from the checklist
func (list *Checklist) Delete() { func (list *Checklist) Delete() {
list.Items = append(list.Items[:list.Selected], list.Items[list.Selected+1:]...) list.Items = append(list.Items[:list.selected], list.Items[list.selected+1:]...)
list.Prev() list.Prev()
} }
@ -53,18 +59,18 @@ func (list *Checklist) Demote() {
return return
} }
j := list.Selected + 1 j := list.selected + 1
if j >= len(list.Items) { if j >= len(list.Items) {
j = 0 j = 0
} }
list.Swap(list.Selected, j) list.Swap(list.selected, j)
list.Selected = j list.selected = j
} }
// IsSelectable returns true if the checklist has selectable items, false if it does not // IsSelectable returns true if the checklist has selectable items, false if it does not
func (list *Checklist) IsSelectable() bool { func (list *Checklist) IsSelectable() bool {
return list.Selected >= 0 && list.Selected < len(list.Items) return list.selected >= 0 && list.selected < len(list.Items)
} }
// IsUnselectable returns true if the checklist has no selectable items, false if it does // IsUnselectable returns true if the checklist has no selectable items, false if it does
@ -74,9 +80,9 @@ func (list *Checklist) IsUnselectable() bool {
// Next selects the next item in the checklist // Next selects the next item in the checklist
func (list *Checklist) Next() { func (list *Checklist) Next() {
list.Selected = list.Selected + 1 list.selected = list.selected + 1
if list.Selected >= len(list.Items) { if list.selected >= len(list.Items) {
list.Selected = 0 list.selected = 0
} }
} }
@ -95,9 +101,9 @@ func (list *Checklist) LongestLine() int {
// Prev selects the previous item in the checklist // Prev selects the previous item in the checklist
func (list *Checklist) Prev() { func (list *Checklist) Prev() {
list.Selected = list.Selected - 1 list.selected = list.selected - 1
if list.Selected < 0 { if list.selected < 0 {
list.Selected = len(list.Items) - 1 list.selected = len(list.Items) - 1
} }
} }
@ -107,13 +113,17 @@ func (list *Checklist) Promote() {
return return
} }
j := list.Selected - 1 j := list.selected - 1
if j < 0 { if j < 0 {
j = len(list.Items) - 1 j = len(list.Items) - 1
} }
list.Swap(list.Selected, j) list.Swap(list.selected, j)
list.Selected = j list.selected = j
}
func (list *Checklist) Selected() int {
return list.selected
} }
// SelectedItem returns the currently-selected checklist item or nil if no item is selected // SelectedItem returns the currently-selected checklist item or nil if no item is selected
@ -122,13 +132,13 @@ func (list *Checklist) SelectedItem() *ChecklistItem {
return nil return nil
} }
return list.Items[list.Selected] return list.Items[list.selected]
} }
func (list *Checklist) SetSelectedByItem(selectableItem *ChecklistItem) { func (list *Checklist) SetSelectedByItem(selectableItem *ChecklistItem) {
for idx, item := range list.Items { for idx, item := range list.Items {
if item == selectableItem { if item == selectableItem {
list.Selected = idx list.selected = idx
break break
} }
} }
@ -158,7 +168,7 @@ func (list *Checklist) UncheckedItems() []*ChecklistItem {
// Unselect removes the current select such that no item is selected // Unselect removes the current select such that no item is selected
func (list *Checklist) Unselect() { func (list *Checklist) Unselect() {
list.Selected = -1 list.selected = -1
} }
// Update sets the text of the currently-selected item to the provided text // Update sets the text of the currently-selected item to the provided text

View File

@ -1,23 +1,36 @@
package checklist package checklist
import ( import ()
"github.com/wtfutil/wtf/wtf"
)
// ChecklistItem is a module for creating generic checklist implementations // ChecklistItem is a module for creating generic checklist implementations
// See 'Todo' for an implementation example // See 'Todo' for an implementation example
type ChecklistItem struct { type ChecklistItem struct {
Checked bool Checked bool
Text string CheckedIcon string
Text string
UncheckedIcon string
}
func NewChecklistItem(checked bool, text string, checkedIcon, uncheckedIcon string) *ChecklistItem {
item := &ChecklistItem{
Checked: checked,
CheckedIcon: checkedIcon,
Text: text,
UncheckedIcon: uncheckedIcon,
}
return item
} }
// CheckMark returns the string used to indicate a ChecklistItem is checked or unchecked // CheckMark returns the string used to indicate a ChecklistItem is checked or unchecked
func (item *ChecklistItem) CheckMark() string { func (item *ChecklistItem) CheckMark() string {
item.ensureItemIcons()
if item.Checked { if item.Checked {
return wtf.Config.UString("wtf.mods.todo.checkedIcon", "x") return item.CheckedIcon
} }
return " " return item.UncheckedIcon
} }
// Toggle changes the checked state of the ChecklistItem // Toggle changes the checked state of the ChecklistItem
@ -25,3 +38,15 @@ func (item *ChecklistItem) CheckMark() string {
func (item *ChecklistItem) Toggle() { func (item *ChecklistItem) Toggle() {
item.Checked = !item.Checked item.Checked = !item.Checked
} }
/* -------------------- Unexported Functions -------------------- */
func (item *ChecklistItem) ensureItemIcons() {
if item.CheckedIcon == "" {
item.CheckedIcon = "x"
}
if item.UncheckedIcon == "" {
item.UncheckedIcon = " "
}
}

View File

@ -16,12 +16,16 @@ const HelpText = `
type Widget struct { type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "{{(Title .Name)}}", "{{(Lower .Name)}}", true), TextWidget: wtf.NewTextWidget(app, "{{(Title .Name)}}", "{{(Lower .Name)}}", true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)

View File

@ -2,7 +2,6 @@ package logger
import ( import (
"fmt" "fmt"
//"io/ioutil"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
@ -18,13 +17,15 @@ type Widget struct {
wtf.TextWidget wtf.TextWidget
filePath string filePath string
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Logs", "logger", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
filePath: logFilePath(), filePath: logFilePath(),
settings: settings,
} }
return &widget return &widget

20
logger/settings.go Normal file
View File

@ -0,0 +1,20 @@
package logger
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "logger"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

175
main.go
View File

@ -151,7 +151,7 @@ func watchForConfigChanges(app *tview.Application, configFilePath string, grid *
loadConfigFile(absPath) loadConfigFile(absPath)
widgets := makeWidgets(app, pages) widgets := makeWidgets(app, pages)
validateWidgets(widgets) wtf.ValidateWidgets(widgets)
initializeFocusTracker(app, widgets) initializeFocusTracker(app, widgets)
@ -182,97 +182,142 @@ func makeWidget(app *tview.Application, pages *tview.Pages, widgetName string) w
// Always in alphabetical order // Always in alphabetical order
switch widgetName { switch widgetName {
case "bamboohr": case "bamboohr":
widget = bamboohr.NewWidget(app) settings := bamboohr.NewSettingsFromYAML("BambooHR", wtf.Config)
widget = bamboohr.NewWidget(app, settings)
case "bargraph": case "bargraph":
widget = bargraph.NewWidget(app) widget = bargraph.NewWidget(app)
case "bittrex": case "bittrex":
widget = bittrex.NewWidget(app) settings := bittrex.NewSettingsFromYAML("Bittrex", wtf.Config)
widget = bittrex.NewWidget(app, settings)
case "blockfolio": case "blockfolio":
widget = blockfolio.NewWidget(app) settings := blockfolio.NewSettingsFromYAML("Blockfolio", wtf.Config)
widget = blockfolio.NewWidget(app, settings)
case "circleci": case "circleci":
widget = circleci.NewWidget(app) settings := circleci.NewSettingsFromYAML("CircleCI", wtf.Config)
widget = circleci.NewWidget(app, settings)
case "clocks": case "clocks":
widget = clocks.NewWidget(app) settings := clocks.NewSettingsFromYAML("Clocks", wtf.Config)
widget = clocks.NewWidget(app, settings)
case "cmdrunner": case "cmdrunner":
widget = cmdrunner.NewWidget(app) settings := cmdrunner.NewSettingsFromYAML("CmdRunner", wtf.Config)
widget = cmdrunner.NewWidget(app, settings)
case "cryptolive": case "cryptolive":
widget = cryptolive.NewWidget(app) settings := cryptolive.NewSettingsFromYAML("CryptoLive", wtf.Config)
widget = cryptolive.NewWidget(app, settings)
case "datadog": case "datadog":
widget = datadog.NewWidget(app) settings := datadog.NewSettingsFromYAML("DataDog", wtf.Config)
widget = datadog.NewWidget(app, settings)
case "gcal": case "gcal":
widget = gcal.NewWidget(app) settings := gcal.NewSettingsFromYAML("Calendar", wtf.Config)
widget = gcal.NewWidget(app, settings)
case "gerrit": case "gerrit":
widget = gerrit.NewWidget(app, pages) settings := gerrit.NewSettingsFromYAML("Gerrit", wtf.Config)
widget = gerrit.NewWidget(app, pages, settings)
case "git": case "git":
widget = git.NewWidget(app, pages) settings := git.NewSettingsFromYAML("Git", wtf.Config)
widget = git.NewWidget(app, pages, settings)
case "github": case "github":
widget = github.NewWidget(app, pages) settings := github.NewSettingsFromYAML("GitHub", wtf.Config)
widget = github.NewWidget(app, pages, settings)
case "gitlab": case "gitlab":
widget = gitlab.NewWidget(app, pages) settings := gitlab.NewSettingsFromYAML("GitLab", wtf.Config)
widget = gitlab.NewWidget(app, pages, settings)
case "gitter": case "gitter":
widget = gitter.NewWidget(app, pages) settings := gitter.NewSettingsFromYAML("Gitter", wtf.Config)
widget = gitter.NewWidget(app, pages, settings)
case "gspreadsheets": case "gspreadsheets":
widget = gspreadsheets.NewWidget(app) settings := gspreadsheets.NewSettingsFromYAML("Google Spreadsheets", wtf.Config)
widget = gspreadsheets.NewWidget(app, settings)
case "hackernews": case "hackernews":
widget = hackernews.NewWidget(app, pages) settings := hackernews.NewSettingsFromYAML("HackerNews", wtf.Config)
widget = hackernews.NewWidget(app, pages, settings)
case "ipapi": case "ipapi":
widget = ipapi.NewWidget(app) settings := ipapi.NewSettingsFromYAML("IPAPI", wtf.Config)
widget = ipapi.NewWidget(app, settings)
case "ipinfo": case "ipinfo":
widget = ipinfo.NewWidget(app) settings := ipinfo.NewSettingsFromYAML("IPInfo", wtf.Config)
widget = ipinfo.NewWidget(app, settings)
case "jenkins": case "jenkins":
widget = jenkins.NewWidget(app, pages) settings := jenkins.NewSettingsFromYAML("Jenkins", wtf.Config)
widget = jenkins.NewWidget(app, pages, settings)
case "jira": case "jira":
widget = jira.NewWidget(app, pages) settings := jira.NewSettingsFromYAML("Jira", wtf.Config)
widget = jira.NewWidget(app, pages, settings)
case "logger": case "logger":
widget = logger.NewWidget(app) settings := logger.NewSettingsFromYAML("Log", wtf.Config)
widget = logger.NewWidget(app, settings)
case "mercurial": case "mercurial":
widget = mercurial.NewWidget(app, pages) settings := mercurial.NewSettingsFromYAML("Mercurial", wtf.Config)
widget = mercurial.NewWidget(app, pages, settings)
case "nbascore": case "nbascore":
widget = nbascore.NewWidget(app, pages) settings := nbascore.NewSettingsFromYAML("NBA Score", wtf.Config)
widget = nbascore.NewWidget(app, pages, settings)
case "newrelic": case "newrelic":
widget = newrelic.NewWidget(app) settings := newrelic.NewSettingsFromYAML("NewRelic", wtf.Config)
widget = newrelic.NewWidget(app, settings)
case "opsgenie": case "opsgenie":
widget = opsgenie.NewWidget(app) settings := opsgenie.NewSettingsFromYAML("OpsGenie", wtf.Config)
widget = opsgenie.NewWidget(app, settings)
case "pagerduty": case "pagerduty":
widget = pagerduty.NewWidget(app) settings := pagerduty.NewSettingsFromYAML("PagerDuty", wtf.Config)
widget = pagerduty.NewWidget(app, settings)
case "power": case "power":
widget = power.NewWidget(app) settings := power.NewSettingsFromYAML("Power", wtf.Config)
widget = power.NewWidget(app, settings)
case "prettyweather": case "prettyweather":
widget = prettyweather.NewWidget(app) settings := prettyweather.NewSettingsFromYAML("Pretty Weather", wtf.Config)
widget = prettyweather.NewWidget(app, settings)
case "resourceusage": case "resourceusage":
widget = resourceusage.NewWidget(app) settings := resourceusage.NewSettingsFromYAML("Resource Usage", wtf.Config)
case "security": widget = resourceusage.NewWidget(app, settings)
widget = security.NewWidget(app)
case "status":
widget = status.NewWidget(app)
case "system":
widget = system.NewWidget(app, date, version)
case "spotify":
widget = spotify.NewWidget(app, pages)
case "spotifyweb":
widget = spotifyweb.NewWidget(app, pages)
case "textfile":
widget = textfile.NewWidget(app, pages)
case "todo":
widget = todo.NewWidget(app, pages)
case "todoist":
widget = todoist.NewWidget(app, pages)
case "travisci":
widget = travisci.NewWidget(app, pages)
case "rollbar": case "rollbar":
widget = rollbar.NewWidget(app, pages) settings := rollbar.NewSettingsFromYAML("Rollbar", wtf.Config)
widget = rollbar.NewWidget(app, pages, settings)
case "security":
settings := security.NewSettingsFromYAML("Security", wtf.Config)
widget = security.NewWidget(app, settings)
case "spotify":
settings := spotify.NewSettingsFromYAML("Spotify", wtf.Config)
widget = spotify.NewWidget(app, pages, settings)
case "spotifyweb":
settings := spotifyweb.NewSettingsFromYAML("Spotify Web", wtf.Config)
widget = spotifyweb.NewWidget(app, pages, settings)
case "status":
settings := status.NewSettingsFromYAML("Status", wtf.Config)
widget = status.NewWidget(app, settings)
case "system":
settings := system.NewSettingsFromYAML("System", wtf.Config)
widget = system.NewWidget(app, date, version, settings)
case "textfile":
settings := textfile.NewSettingsFromYAML("Textfile", wtf.Config)
widget = textfile.NewWidget(app, pages, settings)
case "todo":
settings := todo.NewSettingsFromYAML("Todo", wtf.Config)
widget = todo.NewWidget(app, pages, settings)
case "todoist":
settings := todoist.NewSettingsFromYAML("Todoist", wtf.Config)
widget = todoist.NewWidget(app, pages, settings)
case "travisci":
settings := travisci.NewSettingsFromYAML("TravisCI", wtf.Config)
widget = travisci.NewWidget(app, pages, settings)
case "trello": case "trello":
widget = trello.NewWidget(app) settings := trello.NewSettingsFromYAML("Trello", wtf.Config)
widget = trello.NewWidget(app, settings)
case "twitter": case "twitter":
widget = twitter.NewWidget(app, pages) settings := twitter.NewSettingsFromYAML("Twitter", wtf.Config)
widget = twitter.NewWidget(app, pages, settings)
case "victorops": case "victorops":
widget = victorops.NewWidget(app) settings := victorops.NewSettingsFromYAML("VictorOps - OnCall", wtf.Config)
widget = victorops.NewWidget(app, settings)
case "weather": case "weather":
widget = weather.NewWidget(app, pages) settings := weather.NewSettingsFromYAML("Weather", wtf.Config)
widget = weather.NewWidget(app, pages, settings)
case "zendesk": case "zendesk":
widget = zendesk.NewWidget(app) settings := zendesk.NewSettingsFromYAML("Zendesk", wtf.Config)
widget = zendesk.NewWidget(app, settings)
default: default:
widget = unknown.NewWidget(app, widgetName) settings := unknown.NewSettingsFromYAML(widgetName, wtf.Config)
widget = unknown.NewWidget(app, widgetName, settings)
} }
return widget return widget
@ -297,15 +342,15 @@ func makeWidgets(app *tview.Application, pages *tview.Pages) []wtf.Wtfable {
return widgets return widgets
} }
// Check that all the loaded widgets are valid for display // // Check that all the loaded widgets are valid for display
func validateWidgets(widgets []wtf.Wtfable) { // func validateWidgets(widgets []wtf.Wtfable) {
for _, widget := range widgets { // for _, widget := range widgets {
if widget.Enabled() && !widget.IsPositionable() { // if widget.Enabled() && !widget.IsPositionable() {
errStr := fmt.Sprintf("Widget config has invalid values: %s", widget.Key()) // errStr := fmt.Sprintf("Widget config has invalid values: %s", widget.Key())
log.Fatalln(errStr) // log.Fatalln(errStr)
} // }
} // }
} // }
/* -------------------- Main -------------------- */ /* -------------------- Main -------------------- */
@ -331,7 +376,7 @@ func main() {
pages := tview.NewPages() pages := tview.NewPages()
widgets := makeWidgets(app, pages) widgets := makeWidgets(app, pages)
validateWidgets(widgets) wtf.ValidateWidgets(widgets)
initializeFocusTracker(app, widgets) initializeFocusTracker(app, widgets)

View File

@ -0,0 +1,30 @@
package bamboohr
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "bamboohr"
type Settings struct {
common *cfg.Common
apiKey string
subdomain string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_BAMBOO_HR_TOKEN")),
subdomain: localConfig.UString("subdomain", os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN")),
}
return &settings
}

View File

@ -2,19 +2,24 @@ package bamboohr
import ( import (
"fmt" "fmt"
"os"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
) )
const APIURI = "https://api.bamboohr.com/api/gateway.php"
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "BambooHR", "bamboohr", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -23,17 +28,12 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
apiKey := wtf.Config.UString( client := NewClient(
"wtf.mods.bamboohr.apiKey", APIURI,
os.Getenv("WTF_BAMBOO_HR_TOKEN"), widget.settings.apiKey,
widget.settings.subdomain,
) )
subdomain := wtf.Config.UString(
"wtf.mods.bamboohr.subdomain",
os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN"),
)
client := NewClient("https://api.bamboohr.com/api/gateway.php", apiKey, subdomain)
todayItems := client.Away( todayItems := client.Away(
"timeOff", "timeOff",
wtf.Now().Format(wtf.DateFormat), wtf.Now().Format(wtf.DateFormat),

View File

@ -0,0 +1,28 @@
package circleci
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "circleci"
type Settings struct {
common *cfg.Common
apiKey string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_CIRCLE_API_KEY")),
}
return &settings
}

View File

@ -2,7 +2,6 @@ package circleci
import ( import (
"fmt" "fmt"
"os"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
@ -11,19 +10,16 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
*Client *Client
settings *Settings
} }
const apiEnvKey = "WTF_CIRCLE_API_KEY" func NewWidget(app *tview.Application, settings *Settings) *Widget {
func NewWidget(app *tview.Application) *Widget {
apiKey := wtf.Config.UString(
"wtf.mods.circleci.apiKey",
os.Getenv(apiEnvKey),
)
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "CircleCI", "circleci", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
Client: NewClient(apiKey), Client: NewClient(settings.apiKey),
settings: settings,
} }
return &widget return &widget

View File

@ -3,16 +3,14 @@ package clocks
import ( import (
"sort" "sort"
"time" "time"
"github.com/wtfutil/wtf/wtf"
) )
type ClockCollection struct { type ClockCollection struct {
Clocks []Clock Clocks []Clock
} }
func (clocks *ClockCollection) Sorted() []Clock { func (clocks *ClockCollection) Sorted(sortOrder string) []Clock {
if "chronological" == wtf.Config.UString("wtf.mods.clocks.sort", "alphabetical") { if sortOrder == "chronological" {
clocks.SortedChronologically() clocks.SortedChronologically()
} else { } else {
clocks.SortedAlphabetically() clocks.SortedAlphabetically()

View File

@ -2,8 +2,6 @@ package clocks
import ( import (
"fmt" "fmt"
"github.com/wtfutil/wtf/wtf"
) )
func (widget *Widget) display(clocks []Clock, dateFormat string, timeFormat string) { func (widget *Widget) display(clocks []Clock, dateFormat string, timeFormat string) {
@ -14,9 +12,15 @@ func (widget *Widget) display(clocks []Clock, dateFormat string, timeFormat stri
str := "" str := ""
for idx, clock := range clocks { for idx, clock := range clocks {
rowColor := widget.settings.colors.rows.odd
if idx%2 == 0 {
rowColor = widget.settings.colors.rows.even
}
str = str + fmt.Sprintf( str = str + fmt.Sprintf(
" [%s]%-12s %-10s %7s[white]\n", " [%s]%-12s %-10s %7s[white]\n",
wtf.RowColor("clocks", idx), rowColor,
clock.Label, clock.Label,
clock.Time(timeFormat), clock.Time(timeFormat),
clock.Date(dateFormat), clock.Date(dateFormat),

44
modules/clocks/setting.go Normal file
View File

@ -0,0 +1,44 @@
package clocks
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
"github.com/wtfutil/wtf/wtf"
)
const configKey = "clocks"
type colors struct {
rows struct {
even string
odd string
}
}
type Settings struct {
colors
common *cfg.Common
dateFormat string
timeFormat string
locations map[string]interface{}
sort string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
dateFormat: localConfig.UString("dateFormat", wtf.SimpleDateFormat),
timeFormat: localConfig.UString("timeFormat", wtf.SimpleTimeFormat),
locations: localConfig.UMap("locations"),
sort: localConfig.UString("sort"),
}
settings.colors.rows.even = localConfig.UString("colors.rows.even", "white")
settings.colors.rows.odd = localConfig.UString("colors.rows.odd", "blue")
return &settings
}

View File

@ -14,17 +14,19 @@ type Widget struct {
clockColl ClockCollection clockColl ClockCollection
dateFormat string dateFormat string
timeFormat string timeFormat string
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "World Clocks", "clocks", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
dateFormat: settings.dateFormat,
timeFormat: settings.timeFormat,
} }
widget.clockColl = widget.buildClockCollection(wtf.Config.UMap("wtf.mods.clocks.locations")) widget.clockColl = widget.buildClockCollection(settings.locations)
widget.dateFormat = wtf.Config.UString("wtf.mods.clocks.dateFormat", wtf.SimpleDateFormat)
widget.timeFormat = wtf.Config.UString("wtf.mods.clocks.timeFormat", wtf.SimpleTimeFormat)
return &widget return &widget
} }
@ -32,7 +34,7 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
widget.display(widget.clockColl.Sorted(), widget.dateFormat, widget.timeFormat) widget.display(widget.clockColl.Sorted(widget.settings.sort), widget.dateFormat, widget.timeFormat)
} }
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */

View File

@ -0,0 +1,29 @@
package cmdrunner
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
"github.com/wtfutil/wtf/wtf"
)
const configKey = "cmdrunner"
type Settings struct {
common *cfg.Common
args []string
cmd string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
args: wtf.ToStrs(localConfig.UList("args")),
cmd: localConfig.UString("cmd"),
}
return &settings
}

View File

@ -12,17 +12,19 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
args []string args []string
cmd string cmd string
result string result string
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "CmdRunner", "cmdrunner", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
args: wtf.ToStrs(wtf.Config.UList("wtf.mods.cmdrunner.args")), args: settings.args,
cmd: wtf.Config.UString("wtf.mods.cmdrunner.cmd"), cmd: settings.cmd,
settings: settings,
} }
widget.View.SetWrap(true) widget.View.SetWrap(true)
@ -33,8 +35,8 @@ func NewWidget(app *tview.Application) *Widget {
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
widget.execute() widget.execute()
title := tview.TranslateANSI(wtf.Config.UString("wtf.mods.cmdrunner.title", widget.String())) widget.CommonSettings.Title = widget.String()
widget.View.SetTitle(title) widget.View.SetTitle(tview.TranslateANSI(widget.CommonSettings.Title))
widget.View.SetText(widget.result) widget.View.SetText(widget.result)
} }

View File

@ -12,14 +12,21 @@ func (widget *Widget) display() {
return return
} }
widget.View.SetText(summaryText(&widget.summaryList, &widget.TextColors)) summaryText := widget.summaryText(&widget.summaryList)
widget.View.SetText(summaryText)
} }
func summaryText(list *summaryList, colors *TextColors) string { func (widget *Widget) summaryText(list *summaryList) string {
str := "" str := ""
for _, baseCurrency := range list.items { for _, baseCurrency := range list.items {
str += fmt.Sprintf(" [%s]%s[%s] (%s)\n\n", colors.base.displayName, baseCurrency.displayName, colors.base.name, baseCurrency.name) str += fmt.Sprintf(
" [%s]%s[%s] (%s)\n\n",
widget.settings.colors.base.displayName,
baseCurrency.displayName,
widget.settings.colors.base.name,
baseCurrency.name,
)
resultTemplate := template.New("bittrex") resultTemplate := template.New("bittrex")
@ -38,9 +45,9 @@ func summaryText(list *summaryList, colors *TextColors) string {
) )
strTemplate.Execute(writer, map[string]string{ strTemplate.Execute(writer, map[string]string{
"nameColor": colors.market.name, "nameColor": widget.settings.colors.market.name,
"fieldColor": colors.market.field, "fieldColor": widget.settings.colors.market.field,
"valueColor": colors.market.value, "valueColor": widget.settings.colors.market.value,
"mName": marketCurrency.name, "mName": marketCurrency.name,
"High": marketCurrency.High, "High": marketCurrency.High,
"Low": marketCurrency.Low, "Low": marketCurrency.Low,

View File

@ -0,0 +1,64 @@
package bittrex
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "bittrex"
type colors struct {
base struct {
name string
displayName string
}
market struct {
name string
field string
value string
}
}
type currency struct {
displayName string
market []interface{}
}
type summary struct {
currencies map[string]*currency
}
type Settings struct {
colors
common *cfg.Common
summary
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
settings.colors.base.name = localConfig.UString("colors.base.name")
settings.colors.base.displayName = localConfig.UString("colors.base.displayName")
settings.colors.market.name = localConfig.UString("colors.market.name")
settings.colors.market.field = localConfig.UString("colors.market.field")
settings.colors.market.value = localConfig.UString("colors.market.value")
settings.summary.currencies = make(map[string]*currency)
for key, val := range localConfig.UMap("summary") {
coercedVal := val.(map[string]interface{})
currency := &currency{
displayName: coercedVal["displayName"].(string),
market: coercedVal["market"].([]interface{}),
}
settings.summary.currencies[key] = currency
}
return &settings
}

View File

@ -11,69 +11,48 @@ import (
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
) )
type TextColors struct {
base struct {
name string
displayName string
}
market struct {
name string
field string
value string
}
}
var ok = true var ok = true
var errorText = "" var errorText = ""
var baseURL = "https://bittrex.com/api/v1.1/public/getmarketsummary" const baseURL = "https://bittrex.com/api/v1.1/public/getmarketsummary"
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
summaryList summaryList
TextColors
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Bittrex", "bittrex", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
summaryList: summaryList{}, summaryList: summaryList{},
} }
ok = true ok = true
errorText = "" errorText = ""
widget.config()
widget.setSummaryList() widget.setSummaryList()
return &widget return &widget
} }
func (widget *Widget) config() {
widget.TextColors.base.name = wtf.Config.UString("wtf.mods.bittrex.colors.base.name", "red")
widget.TextColors.base.displayName = wtf.Config.UString("wtf.mods.bittrex.colors.base.displayName", "grey")
widget.TextColors.market.name = wtf.Config.UString("wtf.mods.bittrex.colors.market.name", "red")
widget.TextColors.market.field = wtf.Config.UString("wtf.mods.bittrex.colors.market.field", "coral")
widget.TextColors.market.value = wtf.Config.UString("wtf.mods.bittrex.colors.market.value", "white")
}
func (widget *Widget) setSummaryList() { func (widget *Widget) setSummaryList() {
sCurrencies, _ := wtf.Config.Map("wtf.mods.bittrex.summary") for symbol, currency := range widget.settings.summary.currencies {
for baseCurrencyName := range sCurrencies { mCurrencyList := widget.makeSummaryMarketList(symbol, currency.market)
displayName, _ := wtf.Config.String("wtf.mods.bittrex.summary." + baseCurrencyName + ".displayName") widget.summaryList.addSummaryItem(symbol, currency.displayName, mCurrencyList)
mCurrencyList := makeSummaryMarketList(baseCurrencyName)
widget.summaryList.addSummaryItem(baseCurrencyName, displayName, mCurrencyList)
} }
} }
func makeSummaryMarketList(currencyName string) []*mCurrency { func (widget *Widget) makeSummaryMarketList(currencySymbol string, market []interface{}) []*mCurrency {
mCurrencyList := []*mCurrency{} mCurrencyList := []*mCurrency{}
configMarketList, _ := wtf.Config.List("wtf.mods.bittrex.summary." + currencyName + ".market") for _, marketSymbol := range market {
for _, mCurrencyName := range configMarketList { mCurrencyList = append(mCurrencyList, makeMarketCurrency(marketSymbol.(string)))
mCurrencyList = append(mCurrencyList, makeMarketCurrency(mCurrencyName.(string)))
} }
return mCurrencyList return mCurrencyList

View File

@ -0,0 +1,35 @@
package blockfolio
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "blockfolio"
type colors struct {
name string
grows string
drop string
}
type Settings struct {
colors
common *cfg.Common
deviceToken string
displayHoldings bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
deviceToken: localConfig.UString("device_token"),
displayHoldings: localConfig.UBool("displayHoldings", true),
}
return &settings
}

View File

@ -15,12 +15,15 @@ type Widget struct {
wtf.TextWidget wtf.TextWidget
device_token string device_token string
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Blockfolio", "blockfolio", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
device_token: wtf.Config.UString("wtf.mods.blockfolio.device_token"),
device_token: settings.deviceToken,
settings: settings,
} }
return &widget return &widget
@ -36,31 +39,50 @@ func (widget *Widget) Refresh() {
return return
} }
widget.View.SetText(contentFrom(positions)) content := widget.contentFrom(positions)
widget.View.SetText(content)
} }
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func contentFrom(positions *AllPositionsResponse) string { func (widget *Widget) contentFrom(positions *AllPositionsResponse) string {
res := "" res := ""
colorName := wtf.Config.UString("wtf.mods.blockfolio.colors.name") totalFiat := float32(0.0)
colorGrows := wtf.Config.UString("wtf.mods.blockfolio.colors.grows")
colorDrop := wtf.Config.UString("wtf.mods.blockfolio.colors.drop")
displayHoldings := wtf.Config.UBool("wtf.mods.blockfolio.displayHoldings")
var totalFiat float32
totalFiat = 0.0
for i := 0; i < len(positions.PositionList); i++ { for i := 0; i < len(positions.PositionList); i++ {
colorForChange := colorGrows colorForChange := widget.settings.colors.grows
if positions.PositionList[i].TwentyFourHourPercentChangeFiat <= 0 { if positions.PositionList[i].TwentyFourHourPercentChangeFiat <= 0 {
colorForChange = colorDrop colorForChange = widget.settings.colors.drop
} }
totalFiat += positions.PositionList[i].HoldingValueFiat totalFiat += positions.PositionList[i].HoldingValueFiat
if displayHoldings {
res = res + fmt.Sprintf("[%s]%-6s - %5.2f ([%s]%.3fk [%s]%.2f%s)\n", colorName, positions.PositionList[i].Coin, positions.PositionList[i].Quantity, colorForChange, positions.PositionList[i].HoldingValueFiat/1000, colorForChange, positions.PositionList[i].TwentyFourHourPercentChangeFiat, "%") if widget.settings.displayHoldings {
res = res + fmt.Sprintf(
"[%s]%-6s - %5.2f ([%s]%.3fk [%s]%.2f%s)\n",
widget.settings.colors.name,
positions.PositionList[i].Coin,
positions.PositionList[i].Quantity,
colorForChange,
positions.PositionList[i].HoldingValueFiat/1000,
colorForChange,
positions.PositionList[i].TwentyFourHourPercentChangeFiat,
"%",
)
} else { } else {
res = res + fmt.Sprintf("[%s]%-6s - %5.2f ([%s]%.2f%s)\n", colorName, positions.PositionList[i].Coin, positions.PositionList[i].Quantity, colorForChange, positions.PositionList[i].TwentyFourHourPercentChangeFiat, "%") res = res + fmt.Sprintf(
"[%s]%-6s - %5.2f ([%s]%.2f%s)\n",
widget.settings.colors.name,
positions.PositionList[i].Coin,
positions.PositionList[i].Quantity,
colorForChange,
positions.PositionList[i].TwentyFourHourPercentChangeFiat,
"%",
)
} }
} }
if displayHoldings {
if widget.settings.displayHoldings {
res = res + fmt.Sprintf("\n[%s]Total value: $%.3fk", "green", totalFiat/1000) res = res + fmt.Sprintf("\n[%s]Total value: $%.3fk", "green", totalFiat/1000)
} }

View File

@ -0,0 +1,77 @@
package price
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "cryptolive"
type colors struct {
from struct {
name string
displayName string
}
to struct {
name string
price string
}
top struct {
from struct {
name string
displayName string
}
to struct {
name string
field string
value string
}
}
}
type currency struct {
displayName string
to []interface{}
}
type Settings struct {
colors
common *cfg.Common
currencies map[string]*currency
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
settings.colors.from.name = localConfig.UString("colors.from.name")
settings.colors.from.displayName = localConfig.UString("colors.from.displayName")
settings.colors.to.name = localConfig.UString("colors.to.name")
settings.colors.to.price = localConfig.UString("colors.to.price")
settings.colors.top.from.name = localConfig.UString("colors.top.from.name")
settings.colors.top.from.displayName = localConfig.UString("colors.top.from.displayName")
settings.colors.top.to.name = localConfig.UString("colors.top.to.name")
settings.colors.top.to.field = localConfig.UString("colors.top.to.field")
settings.colors.top.to.value = localConfig.UString("colors.top.to.value")
settings.currencies = make(map[string]*currency)
for key, val := range localConfig.UMap("currencies") {
coercedVal := val.(map[string]interface{})
currency := &currency{
displayName: coercedVal["displayName"].(string),
to: coercedVal["to"].([]interface{}),
}
settings.currencies[key] = currency
}
return &settings
}

View File

@ -6,8 +6,6 @@ import (
"net/http" "net/http"
"sync" "sync"
"time" "time"
"github.com/wtfutil/wtf/wtf"
) )
var baseURL = "https://min-api.cryptocompare.com/data/price" var baseURL = "https://min-api.cryptocompare.com/data/price"
@ -16,6 +14,7 @@ var ok = true
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
*list *list
settings *Settings
Result string Result string
@ -23,8 +22,10 @@ type Widget struct {
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget() *Widget { func NewWidget(settings *Settings) *Widget {
widget := Widget{} widget := Widget{
settings: settings,
}
widget.setList() widget.setList()
@ -32,16 +33,12 @@ func NewWidget() *Widget {
} }
func (widget *Widget) setList() { func (widget *Widget) setList() {
currenciesMap, _ := wtf.Config.Map("wtf.mods.cryptolive.currencies")
widget.list = &list{} widget.list = &list{}
for currency := range currenciesMap { for symbol, currency := range widget.settings.currencies {
displayName, _ := wtf.Config.String("wtf.mods.cryptolive.currencies." + currency + ".displayName") toList := widget.getToList(symbol)
toList := getToList(currency) widget.list.addItem(symbol, currency.displayName, toList)
widget.list.addItem(currency, displayName, toList)
} }
} }
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
@ -66,16 +63,23 @@ func (widget *Widget) Refresh(wg *sync.WaitGroup) {
func (widget *Widget) display() { func (widget *Widget) display() {
str := "" str := ""
var (
fromNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.from.name", "coral")
fromDisplayNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.from.displayName", "grey")
toNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.to.name", "white")
toPriceColor = wtf.Config.UString("wtf.mods.cryptolive.colors.to.price", "green")
)
for _, item := range widget.list.items { for _, item := range widget.list.items {
str += fmt.Sprintf(" [%s]%s[%s] (%s)\n", fromNameColor, item.displayName, fromDisplayNameColor, item.name) str += fmt.Sprintf(
" [%s]%s[%s] (%s)\n",
widget.settings.colors.from.name,
item.displayName,
widget.settings.colors.from.name,
item.name,
)
for _, toItem := range item.to { for _, toItem := range item.to {
str += fmt.Sprintf("\t[%s]%s: [%s]%f\n", toNameColor, toItem.name, toPriceColor, toItem.price) str += fmt.Sprintf(
"\t[%s]%s: [%s]%f\n",
widget.settings.colors.to.name,
toItem.name,
widget.settings.colors.to.price,
toItem.price,
)
} }
str += "\n" str += "\n"
} }
@ -83,12 +87,10 @@ func (widget *Widget) display() {
widget.Result = fmt.Sprintf("\n%s", str) widget.Result = fmt.Sprintf("\n%s", str)
} }
func getToList(fromName string) []*toCurrency { func (widget *Widget) getToList(symbol string) []*toCurrency {
toNames, _ := wtf.Config.List("wtf.mods.cryptolive.currencies." + fromName + ".to")
var toList []*toCurrency var toList []*toCurrency
for _, to := range toNames { for _, to := range widget.settings.currencies[symbol].to {
toList = append(toList, &toCurrency{ toList = append(toList, &toCurrency{
name: to.(string), name: to.(string),
price: 0, price: 0,

View File

@ -0,0 +1,75 @@
package cryptolive
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
"github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive/price"
"github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive/toplist"
)
const configKey = "cryptolive"
type colors struct {
from struct {
name string
displayName string
}
to struct {
name string
price string
}
top struct {
from struct {
name string
displayName string
}
to struct {
name string
field string
value string
}
}
}
type Settings struct {
colors
common *cfg.Common
currencies map[string]interface{}
top map[string]interface{}
priceSettings *price.Settings
toplistSettings *toplist.Settings
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
currencies, _ := localConfig.Map("currencies")
top, _ := localConfig.Map("top")
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
currencies: currencies,
top: top,
priceSettings: price.NewSettingsFromYAML(name, ymlConfig),
toplistSettings: toplist.NewSettingsFromYAML(name, ymlConfig),
}
settings.colors.from.name = localConfig.UString("colors.from.name")
settings.colors.from.displayName = localConfig.UString("colors.from.displayName")
settings.colors.to.name = localConfig.UString("colors.to.name")
settings.colors.to.price = localConfig.UString("colors.to.price")
settings.colors.top.from.name = localConfig.UString("colors.top.from.name")
settings.colors.top.from.displayName = localConfig.UString("colors.top.from.displayName")
settings.colors.top.to.name = localConfig.UString("colors.top.to.name")
settings.colors.top.to.field = localConfig.UString("colors.top.to.field")
settings.colors.top.to.value = localConfig.UString("colors.top.to.value")
return &settings
}

View File

@ -7,49 +7,54 @@ func (widget *Widget) display() {
for _, fromCurrency := range widget.list.items { for _, fromCurrency := range widget.list.items {
str += fmt.Sprintf( str += fmt.Sprintf(
"[%s]%s [%s](%s)\n", "[%s]%s [%s](%s)\n",
widget.colors.from.displayName, widget.settings.colors.from.displayName,
fromCurrency.displayName, fromCurrency.displayName,
widget.colors.from.name, widget.settings.colors.from.name,
fromCurrency.name, fromCurrency.name,
) )
str += makeToListText(fromCurrency.to, widget.colors) str += widget.makeToListText(fromCurrency.to)
} }
widget.Result = str widget.Result = str
} }
func makeToListText(toList []*tCurrency, colors textColors) string { func (widget *Widget) makeToListText(toList []*tCurrency) string {
str := "" str := ""
for _, toCurrency := range toList { for _, toCurrency := range toList {
str += makeToText(toCurrency, colors) str += widget.makeToText(toCurrency)
} }
return str return str
} }
func makeToText(toCurrency *tCurrency, colors textColors) string { func (widget *Widget) makeToText(toCurrency *tCurrency) string {
str := "" str := ""
str += fmt.Sprintf(" [%s]%s\n", colors.to.name, toCurrency.name) str += fmt.Sprintf(
" [%s]%s\n",
widget.settings.colors.to.name,
toCurrency.name,
)
for _, info := range toCurrency.info { for _, info := range toCurrency.info {
str += makeInfoText(info, colors) str += widget.makeInfoText(info)
str += "\n\n" str += "\n\n"
} }
return str return str
} }
func makeInfoText(info tInfo, colors textColors) string { func (widget *Widget) makeInfoText(info tInfo) string {
return fmt.Sprintf( return fmt.Sprintf(
" [%s]Exchange: [%s]%s\n", " [%s]Exchange: [%s]%s\n",
colors.to.field, widget.settings.colors.top.to.field,
colors.to.value, widget.settings.colors.top.to.value,
info.exchange, info.exchange,
) + ) +
fmt.Sprintf( fmt.Sprintf(
" [%s]Volume(24h): [%s]%f-[%s]%f", " [%s]Volume(24h): [%s]%f-[%s]%f",
colors.to.field, widget.settings.colors.top.to.field,
colors.to.value, widget.settings.colors.top.to.value,
info.volume24h, info.volume24h,
colors.to.value, widget.settings.colors.top.to.value,
info.volume24hTo, info.volume24hTo,
) )
} }

View File

@ -0,0 +1,96 @@
package toplist
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "cryptolive"
type colors struct {
from struct {
name string
displayName string
}
to struct {
name string
price string
}
top struct {
from struct {
name string
displayName string
}
to struct {
name string
field string
value string
}
}
}
type currency struct {
displayName string
limit int
to []interface{}
}
type Settings struct {
colors
common *cfg.Common
currencies map[string]*currency
top map[string]*currency
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
settings.colors.from.name = localConfig.UString("colors.from.name")
settings.colors.from.displayName = localConfig.UString("colors.from.displayName")
settings.colors.to.name = localConfig.UString("colors.to.name")
settings.colors.to.price = localConfig.UString("colors.to.price")
settings.colors.top.from.name = localConfig.UString("colors.top.from.name")
settings.colors.top.from.displayName = localConfig.UString("colors.top.from.displayName")
settings.colors.top.to.name = localConfig.UString("colors.top.to.name")
settings.colors.top.to.field = localConfig.UString("colors.top.to.field")
settings.colors.top.to.value = localConfig.UString("colors.top.to.value")
settings.currencies = make(map[string]*currency)
for key, val := range localConfig.UMap("currencies") {
coercedVal := val.(map[string]interface{})
limit, _ := coercedVal["limit"].(int)
currency := &currency{
displayName: coercedVal["displayName"].(string),
limit: limit,
to: coercedVal["to"].([]interface{}),
}
settings.currencies[key] = currency
}
for key, val := range localConfig.UMap("top") {
coercedVal := val.(map[string]interface{})
limit, _ := coercedVal["limit"].(int)
currency := &currency{
displayName: coercedVal["displayName"].(string),
limit: limit,
to: coercedVal["to"].([]interface{}),
}
settings.currencies[key] = currency
}
return &settings
}

View File

@ -7,62 +7,43 @@ import (
"os" "os"
"sync" "sync"
"time" "time"
"github.com/wtfutil/wtf/wtf"
) )
var baseURL = "https://min-api.cryptocompare.com/data/top/exchanges" var baseURL = "https://min-api.cryptocompare.com/data/top/exchanges"
type textColors struct {
from struct {
name string
displayName string
}
to struct {
name string
field string
value string
}
}
// Widget Toplist Widget // Widget Toplist Widget
type Widget struct { type Widget struct {
Result string Result string
RefreshInterval int RefreshInterval int
list *cList list *cList
settings *Settings
colors textColors
} }
// NewWidget Make new toplist widget // NewWidget Make new toplist widget
func NewWidget() *Widget { func NewWidget(settings *Settings) *Widget {
widget := Widget{} widget := Widget{
settings: settings,
}
widget.list = &cList{} widget.list = &cList{}
widget.setList() widget.setList()
widget.config()
return &widget return &widget
} }
func (widget *Widget) setList() { func (widget *Widget) setList() {
currenciesMap, _ := wtf.Config.Map("wtf.mods.cryptolive.top") for symbol, currency := range widget.settings.top {
toList := widget.makeToList(symbol, currency.limit)
for fromCurrency := range currenciesMap { widget.list.addItem(symbol, currency.displayName, currency.limit, toList)
displayName := wtf.Config.UString("wtf.mods.cryptolive.top."+fromCurrency+".displayName", "")
limit := wtf.Config.UInt("wtf.mods.cryptolive.top."+fromCurrency+".limit", 1)
widget.list.addItem(fromCurrency, displayName, limit, makeToList(fromCurrency, limit))
} }
} }
func makeToList(fCurrencyName string, limit int) (list []*tCurrency) { func (widget *Widget) makeToList(symbol string, limit int) (list []*tCurrency) {
toList, _ := wtf.Config.List("wtf.mods.cryptolive.top." + fCurrencyName + ".to") for _, to := range widget.settings.top[symbol].to {
for _, toCurrency := range toList {
list = append(list, &tCurrency{ list = append(list, &tCurrency{
name: toCurrency.(string), name: to.(string),
info: make([]tInfo, limit), info: make([]tInfo, limit),
}) })
} }
@ -70,15 +51,6 @@ func makeToList(fCurrencyName string, limit int) (list []*tCurrency) {
return return
} }
func (widget *Widget) config() {
// set colors
widget.colors.from.name = wtf.Config.UString("wtf.mods.cryptolive.colors.top.from.name", "coral")
widget.colors.from.displayName = wtf.Config.UString("wtf.mods.cryptolive.colors.top.from.displayName", "grey")
widget.colors.to.name = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.name", "red")
widget.colors.to.field = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.field", "white")
widget.colors.to.value = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.value", "value")
}
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
// Refresh & update after interval time // Refresh & update after interval time

View File

@ -13,16 +13,20 @@ import (
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
priceWidget *price.Widget priceWidget *price.Widget
toplistWidget *toplist.Widget toplistWidget *toplist.Widget
settings *Settings
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "CryptoLive", "cryptolive", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
priceWidget: price.NewWidget(),
toplistWidget: toplist.NewWidget(), priceWidget: price.NewWidget(settings.priceSettings),
toplistWidget: toplist.NewWidget(settings.toplistSettings),
settings: settings,
} }
widget.priceWidget.RefreshInterval = widget.RefreshInterval() widget.priceWidget.RefreshInterval = widget.RefreshInterval()

View File

@ -1,34 +1,23 @@
package datadog package datadog
import ( import (
"os"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
datadog "github.com/zorkian/go-datadog-api" datadog "github.com/zorkian/go-datadog-api"
) )
// Monitors returns a list of newrelic monitors // Monitors returns a list of newrelic monitors
func Monitors() ([]datadog.Monitor, error) { func (widget *Widget) Monitors() ([]datadog.Monitor, error) {
client := datadog.NewClient(apiKey(), applicationKey()) client := datadog.NewClient(
widget.settings.apiKey,
widget.settings.applicationKey,
)
monitors, err := client.GetMonitorsByTags(wtf.ToStrs(wtf.Config.UList("wtf.mods.datadog.monitors.tags"))) tags := wtf.ToStrs(widget.settings.tags)
monitors, err := client.GetMonitorsByTags(tags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return monitors, nil return monitors, nil
} }
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.datadog.apiKey",
os.Getenv("WTF_DATADOG_API_KEY"),
)
}
func applicationKey() string {
return wtf.Config.UString(
"wtf.mods.datadog.applicationKey",
os.Getenv("WTF_DATADOG_APPLICATION_KEY"),
)
}

View File

@ -0,0 +1,32 @@
package datadog
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "datadog"
type Settings struct {
common *cfg.Common
apiKey string
applicationKey string
tags []interface{}
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_DATADOG_API_KEY")),
applicationKey: localConfig.UString("applicationKey", os.Getenv("WTF_DATADOG_APPLICATION_KEY")),
tags: localConfig.UList("monitors.tags"),
}
return &settings
}

View File

@ -10,11 +10,15 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Datadog", "datadog", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -23,7 +27,7 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
monitors, monitorErr := Monitors() monitors, monitorErr := widget.Monitors()
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s", widget.Name()))) widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s", widget.Name())))
widget.View.Clear() widget.View.Clear()

View File

@ -27,10 +27,10 @@ import (
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func Fetch() ([]*CalEvent, error) { func (widget *Widget) Fetch() ([]*CalEvent, error) {
ctx := context.Background() ctx := context.Background()
secretPath, _ := wtf.ExpandHomeDir(wtf.Config.UString("wtf.mods.gcal.secretFile")) secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile)
b, err := ioutil.ReadFile(secretPath) b, err := ioutil.ReadFile(secretPath)
if err != nil { if err != nil {
@ -48,13 +48,13 @@ func Fetch() ([]*CalEvent, error) {
return nil, err return nil, err
} }
calendarIds, err := getCalendarIdList(srv) calendarIds, err := widget.getCalendarIdList(srv)
// Get calendar events // Get calendar events
var events calendar.Events var events calendar.Events
startTime := fromMidnight().Format(time.RFC3339) startTime := fromMidnight().Format(time.RFC3339)
eventLimit := int64(wtf.Config.UInt("wtf.mods.gcal.eventCount", 10)) eventLimit := int64(widget.settings.eventCount)
for _, calendarId := range calendarIds { for _, calendarId := range calendarIds {
calendarEvents, err := srv.Events.List(calendarId).ShowDeleted(false).TimeMin(startTime).MaxResults(eventLimit).SingleEvents(true).OrderBy("startTime").Do() calendarEvents, err := srv.Events.List(calendarId).ShowDeleted(false).TimeMin(startTime).MaxResults(eventLimit).SingleEvents(true).OrderBy("startTime").Do()
@ -122,13 +122,12 @@ func isAuthenticated() bool {
return err == nil return err == nil
} }
func authenticate() { func (widget *Widget) authenticate() {
filename := wtf.Config.UString("wtf.mods.gcal.secretFile") secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile)
secretPath, _ := wtf.ExpandHomeDir(filename)
b, err := ioutil.ReadFile(secretPath) b, err := ioutil.ReadFile(secretPath)
if err != nil { if err != nil {
log.Fatalf("Unable to read secret file. %v", filename) log.Fatalf("Unable to read secret file. %v", widget.settings.secretFile)
} }
config, err := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope) config, err := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope)
@ -188,9 +187,9 @@ func saveToken(file string, token *oauth2.Token) {
json.NewEncoder(f).Encode(token) json.NewEncoder(f).Encode(token)
} }
func getCalendarIdList(srv *calendar.Service) ([]string, error) { func (widget *Widget) getCalendarIdList(srv *calendar.Service) ([]string, error) {
// Return single calendar if settings specify we should // Return single calendar if settings specify we should
if !wtf.Config.UBool("wtf.mods.gcal.multiCalendar", false) { if !widget.settings.multiCalendar {
id, err := srv.CalendarList.Get("primary").Do() id, err := srv.CalendarList.Get("primary").Do()
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -32,7 +32,7 @@ func (widget *Widget) display() {
widget.mutex.Lock() widget.mutex.Lock()
defer widget.mutex.Unlock() defer widget.mutex.Unlock()
widget.View.SetTitle(widget.ContextualTitle(widget.Name())) widget.View.SetTitle(widget.ContextualTitle(widget.settings.common.Title))
widget.View.SetText(widget.contentFrom(widget.calEvents)) widget.View.SetText(widget.contentFrom(widget.calEvents))
} }
@ -44,8 +44,8 @@ func (widget *Widget) contentFrom(calEvents []*CalEvent) string {
var str string var str string
var prevEvent *CalEvent var prevEvent *CalEvent
if !wtf.Config.UBool("wtf.mods.gcal.showDeclined", false) { if !widget.settings.showDeclined {
calEvents = removeDeclined(calEvents) calEvents = widget.removeDeclined(calEvents)
} }
for _, calEvent := range calEvents { for _, calEvent := range calEvents {
@ -101,7 +101,7 @@ func (widget *Widget) dayDivider(event, prevEvent *CalEvent) string {
if !eventStartDay.Equal(prevStartDay) { if !eventStartDay.Equal(prevStartDay) {
return fmt.Sprintf("[%s::b]", return fmt.Sprintf("[%s::b]",
wtf.Config.UString("wtf.mods.gcal.colors.day", "forestgreen")) + widget.settings.colors.day) +
event.Start().Format(wtf.FullDateFormat) + event.Start().Format(wtf.FullDateFormat) +
"\n" "\n"
} }
@ -111,10 +111,10 @@ func (widget *Widget) dayDivider(event, prevEvent *CalEvent) string {
func (widget *Widget) descriptionColor(calEvent *CalEvent) string { func (widget *Widget) descriptionColor(calEvent *CalEvent) string {
if calEvent.Past() { if calEvent.Past() {
return wtf.Config.UString("wtf.mods.gcal.colors.past", "gray") return widget.settings.colors.past
} }
return wtf.Config.UString("wtf.mods.gcal.colors.description", "white") return widget.settings.colors.description
} }
func (widget *Widget) eventSummary(calEvent *CalEvent, conflict bool) string { func (widget *Widget) eventSummary(calEvent *CalEvent, conflict bool) string {
@ -123,13 +123,13 @@ func (widget *Widget) eventSummary(calEvent *CalEvent, conflict bool) string {
if calEvent.Now() { if calEvent.Now() {
summary = fmt.Sprintf( summary = fmt.Sprintf(
"%s %s", "%s %s",
wtf.Config.UString("wtf.mods.gcal.currentIcon", "🔸"), widget.settings.currentIcon,
summary, summary,
) )
} }
if conflict { if conflict {
return fmt.Sprintf("%s %s", wtf.Config.UString("wtf.mods.gcal.conflictIcon", "🚨"), summary) return fmt.Sprintf("%s %s", widget.settings.conflictIcon, summary)
} }
return summary return summary
@ -170,9 +170,9 @@ func (widget *Widget) timeUntil(calEvent *CalEvent) string {
} }
func (widget *Widget) titleColor(calEvent *CalEvent) string { func (widget *Widget) titleColor(calEvent *CalEvent) string {
color := wtf.Config.UString("wtf.mods.gcal.colors.title", "white") color := widget.settings.colors.title
for _, untypedArr := range wtf.Config.UList("wtf.mods.gcal.colors.highlights") { for _, untypedArr := range widget.settings.highlights {
highlightElements := wtf.ToStrs(untypedArr.([]interface{})) highlightElements := wtf.ToStrs(untypedArr.([]interface{}))
match, _ := regexp.MatchString( match, _ := regexp.MatchString(
@ -186,14 +186,14 @@ func (widget *Widget) titleColor(calEvent *CalEvent) string {
} }
if calEvent.Past() { if calEvent.Past() {
color = wtf.Config.UString("wtf.mods.gcal.colors.past", "gray") color = widget.settings.colors.past
} }
return color return color
} }
func (widget *Widget) location(calEvent *CalEvent) string { func (widget *Widget) location(calEvent *CalEvent) string {
if wtf.Config.UBool("wtf.mods.gcal.displayLocation", true) == false { if widget.settings.withLocation == false {
return "" return ""
} }
@ -209,13 +209,13 @@ func (widget *Widget) location(calEvent *CalEvent) string {
} }
func (widget *Widget) responseIcon(calEvent *CalEvent) string { func (widget *Widget) responseIcon(calEvent *CalEvent) string {
if false == wtf.Config.UBool("wtf.mods.gcal.displayResponseStatus", true) { if widget.settings.displayResponseStatus == false {
return "" return ""
} }
icon := "[gray]" icon := "[gray]"
switch calEvent.ResponseFor(wtf.Config.UString("wtf.mods.gcal.email")) { switch calEvent.ResponseFor(widget.settings.email) {
case "accepted": case "accepted":
return icon + "✔︎" return icon + "✔︎"
case "declined": case "declined":
@ -229,10 +229,10 @@ func (widget *Widget) responseIcon(calEvent *CalEvent) string {
} }
} }
func removeDeclined(events []*CalEvent) []*CalEvent { func (widget *Widget) removeDeclined(events []*CalEvent) []*CalEvent {
var ret []*CalEvent var ret []*CalEvent
for _, e := range events { for _, e := range events {
if e.ResponseFor(wtf.Config.UString("wtf.mods.gcal.email")) != "declined" { if e.ResponseFor(widget.settings.email) != "declined" {
ret = append(ret, e) ret = append(ret, e)
} }
} }

59
modules/gcal/settings.go Normal file
View File

@ -0,0 +1,59 @@
package gcal
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "gcal"
type colors struct {
day string
description string
past string
title string
highlights []interface{}
}
type Settings struct {
colors
common *cfg.Common
conflictIcon string
currentIcon string
displayResponseStatus bool
email string
eventCount int
multiCalendar bool
secretFile string
showDeclined bool
textInterval int
withLocation bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
conflictIcon: localConfig.UString("conflictIcon", "🚨"),
currentIcon: localConfig.UString("currentIcon", "🔸"),
displayResponseStatus: localConfig.UBool("displayResponseStatus", true),
email: localConfig.UString("email", ""),
eventCount: localConfig.UInt("eventCount", 10),
multiCalendar: localConfig.UBool("multiCalendar", false),
secretFile: localConfig.UString("secretFile", ""),
showDeclined: localConfig.UBool("showDeclined", false),
textInterval: localConfig.UInt("textInterval", 30),
withLocation: localConfig.UBool("withLocation", true),
}
settings.colors.day = localConfig.UString("colors.day", "forestgreen")
settings.colors.description = localConfig.UString("colors.description", "white")
settings.colors.past = localConfig.UString("colors.past", "gray")
settings.colors.title = localConfig.UString("colors.title", "white")
return &settings
}

View File

@ -11,17 +11,20 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
app *tview.Application
calEvents []*CalEvent calEvents []*CalEvent
ch chan struct{} ch chan struct{}
mutex sync.Mutex mutex sync.Mutex
app *tview.Application settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Calendar", "gcal", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
ch: make(chan struct{}),
app: app, app: app,
ch: make(chan struct{}),
settings: settings,
} }
go updateLoop(&widget) go updateLoop(&widget)
@ -41,14 +44,14 @@ func (widget *Widget) Refresh() {
widget.fetchAndDisplayEvents() widget.fetchAndDisplayEvents()
return return
} }
widget.app.Suspend(authenticate) widget.app.Suspend(widget.authenticate)
widget.Refresh() widget.Refresh()
} }
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func (widget *Widget) fetchAndDisplayEvents() { func (widget *Widget) fetchAndDisplayEvents() {
calEvents, err := Fetch() calEvents, err := widget.Fetch()
if err != nil { if err != nil {
widget.calEvents = []*CalEvent{} widget.calEvents = []*CalEvent{}
} else { } else {
@ -58,12 +61,11 @@ func (widget *Widget) fetchAndDisplayEvents() {
} }
func updateLoop(widget *Widget) { func updateLoop(widget *Widget) {
interval := wtf.Config.UInt("wtf.mods.gcal.textInterval", 30) if widget.settings.textInterval == 0 {
if interval == 0 {
return return
} }
tick := time.NewTicker(time.Duration(interval) * time.Second) tick := time.NewTicker(time.Duration(widget.settings.textInterval) * time.Second)
defer tick.Stop() defer tick.Stop()
outer: outer:
for { for {

View File

@ -21,10 +21,10 @@ func (widget *Widget) display() {
str = str + widget.displayStats(project) str = str + widget.displayStats(project)
str = str + "\n" str = str + "\n"
str = str + " [red]Open Incoming Reviews[white]\n" str = str + " [red]Open Incoming Reviews[white]\n"
str = str + widget.displayMyIncomingReviews(project, wtf.Config.UString("wtf.mods.gerrit.username")) str = str + widget.displayMyIncomingReviews(project, widget.settings.username)
str = str + "\n" str = str + "\n"
str = str + " [red]My Outgoing Reviews[white]\n" str = str + " [red]My Outgoing Reviews[white]\n"
str = str + widget.displayMyOutgoingReviews(project, wtf.Config.UString("wtf.mods.gerrit.username")) str = str + widget.displayMyOutgoingReviews(project, widget.settings.username)
widget.View.SetText(str) widget.View.SetText(str)
} }

View File

@ -2,7 +2,6 @@ package gerrit
import ( import (
glb "github.com/andygrunwald/go-gerrit" glb "github.com/andygrunwald/go-gerrit"
"github.com/wtfutil/wtf/wtf"
) )
type GerritProject struct { type GerritProject struct {
@ -25,8 +24,7 @@ func NewGerritProject(path string, gerrit *glb.Client) *GerritProject {
} }
// Refresh reloads the gerrit data via the Gerrit API // Refresh reloads the gerrit data via the Gerrit API
func (project *GerritProject) Refresh() { func (project *GerritProject) Refresh(username string) {
username := wtf.Config.UString("wtf.mods.gerrit.username")
project.Changes, _ = project.loadChanges() project.Changes, _ = project.loadChanges()
project.ReviewCount = project.countReviews(project.Changes) project.ReviewCount = project.countReviews(project.Changes)

View File

@ -0,0 +1,47 @@
package gerrit
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
type colors struct {
rows struct {
even string
odd string
}
}
const configKey = "gerrit"
type Settings struct {
colors
common *cfg.Common
domain string
password string
projects []interface{}
username string
verifyServerCertificate bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
domain: localConfig.UString("domain", ""),
password: localConfig.UString("password", os.Getenv("WTF_GERRIT_PASSWORD")),
projects: localConfig.UList("projects"),
username: localConfig.UString("username", ""),
verifyServerCertificate: localConfig.UBool("verifyServerCertificate", true),
}
settings.colors.rows.even = localConfig.UString("colors.rows.even", "white")
settings.colors.rows.odd = localConfig.UString("colors.rows.odd", "blue")
return &settings
}

View File

@ -4,7 +4,6 @@ import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"net/http" "net/http"
"os"
"regexp" "regexp"
glb "github.com/andygrunwald/go-gerrit" glb "github.com/andygrunwald/go-gerrit"
@ -40,18 +39,20 @@ type Widget struct {
GerritProjects []*GerritProject GerritProjects []*GerritProject
Idx int Idx int
selected int selected int
settings *Settings
} }
var ( var (
GerritURLPattern = regexp.MustCompile(`^(http|https)://(.*)$`) GerritURLPattern = regexp.MustCompile(`^(http|https)://(.*)$`)
) )
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Gerrit", "gerrit", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
Idx: 0, Idx: 0,
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
@ -65,31 +66,27 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
baseURL := wtf.Config.UString("wtf.mods.gerrit.domain") httpClient := &http.Client{
username := wtf.Config.UString("wtf.mods.gerrit.username") Transport: &http.Transport{
TLSClientConfig: &tls.Config{
password := wtf.Config.UString( InsecureSkipVerify: !widget.settings.verifyServerCertificate,
"wtf.mods.gerrit.password", },
os.Getenv("WTF_GERRIT_PASSWORD"), Proxy: http.ProxyFromEnvironment,
)
verifyServerCertificate := wtf.Config.UBool("wtf.mods.gerrit.verifyServerCertificate", true)
httpClient := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: !verifyServerCertificate,
}, },
Proxy: http.ProxyFromEnvironment,
},
} }
gerritUrl := baseURL gerritUrl := widget.settings.domain
submatches := GerritURLPattern.FindAllStringSubmatch(baseURL, -1) submatches := GerritURLPattern.FindAllStringSubmatch(widget.settings.domain, -1)
if len(submatches) > 0 && len(submatches[0]) > 2 { if len(submatches) > 0 && len(submatches[0]) > 2 {
submatch := submatches[0] submatch := submatches[0]
gerritUrl = fmt.Sprintf( gerritUrl = fmt.Sprintf(
"%s://%s:%s@%s", submatch[1], username, password, submatch[2]) "%s://%s:%s@%s",
submatch[1],
widget.settings.username,
widget.settings.password,
submatch[2],
)
} }
gerrit, err := glb.NewClient(gerritUrl, httpClient) gerrit, err := glb.NewClient(gerritUrl, httpClient)
if err != nil { if err != nil {
@ -99,10 +96,10 @@ func (widget *Widget) Refresh() {
return return
} }
widget.gerrit = gerrit widget.gerrit = gerrit
widget.GerritProjects = widget.buildProjectCollection(wtf.Config.UList("wtf.mods.gerrit.projects")) widget.GerritProjects = widget.buildProjectCollection(widget.settings.projects)
for _, project := range widget.GerritProjects { for _, project := range widget.GerritProjects {
project.Refresh() project.Refresh(widget.settings.username)
} }
widget.display() widget.display()
@ -159,7 +156,7 @@ func (widget *Widget) openReview() {
} else { } else {
change = project.OutgoingReviews[sel-len(project.IncomingReviews)] change = project.OutgoingReviews[sel-len(project.IncomingReviews)]
} }
wtf.OpenFile(fmt.Sprintf("%s/%s/%d", wtf.Config.UString("wtf.mods.gerrit.domain"), "#/c", change.Number)) wtf.OpenFile(fmt.Sprintf("%s/%s/%d", widget.settings.domain, "#/c", change.Number))
} }
} }

View File

@ -16,12 +16,12 @@ type GitRepo struct {
Path string Path string
} }
func NewGitRepo(repoPath string) *GitRepo { func NewGitRepo(repoPath string, commitCount int, commitFormat, dateFormat string) *GitRepo {
repo := GitRepo{Path: repoPath} repo := GitRepo{Path: repoPath}
repo.Branch = repo.branch() repo.Branch = repo.branch()
repo.ChangedFiles = repo.changedFiles() repo.ChangedFiles = repo.changedFiles()
repo.Commits = repo.commits() repo.Commits = repo.commits(commitCount, commitFormat, dateFormat)
repo.Repository = strings.TrimSpace(repo.repository()) repo.Repository = strings.TrimSpace(repo.repository())
return &repo return &repo
@ -49,13 +49,9 @@ func (repo *GitRepo) changedFiles() []string {
return data return data
} }
func (repo *GitRepo) commits() []string { func (repo *GitRepo) commits(commitCount int, commitFormat, dateFormat string) []string {
numStr := fmt.Sprintf("-n %d", wtf.Config.UInt("wtf.mods.git.commitCount", 10))
dateFormat := wtf.Config.UString("wtf.mods.git.dateFormat", "%b %d, %Y")
dateStr := fmt.Sprintf("--date=format:\"%s\"", dateFormat) dateStr := fmt.Sprintf("--date=format:\"%s\"", dateFormat)
numStr := fmt.Sprintf("-n %d", commitCount)
commitFormat := wtf.Config.UString("wtf.mods.git.commitFormat", "[forestgreen]%h [white]%s [grey]%an on %cd[white]")
commitStr := fmt.Sprintf("--pretty=format:\"%s\"", commitFormat) commitStr := fmt.Sprintf("--pretty=format:\"%s\"", commitFormat)
arg := []string{repo.gitDir(), repo.workTree(), "log", dateStr, numStr, commitStr} arg := []string{repo.gitDir(), repo.workTree(), "log", dateStr, numStr, commitStr}

32
modules/git/settings.go Normal file
View File

@ -0,0 +1,32 @@
package git
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "git"
type Settings struct {
common *cfg.Common
commitCount int
commitFormat string
dateFormat string
repositories []interface{}
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
commitCount: localConfig.UInt("commitCount", 10),
commitFormat: localConfig.UString("commitFormat", "[forestgreen]%h [white]%s [grey]%an on %cd[white]"),
dateFormat: localConfig.UString("dateFormat", "%b %d, %Y"),
repositories: localConfig.UList("repositories"),
}
return &settings
}

View File

@ -32,19 +32,22 @@ type Widget struct {
wtf.MultiSourceWidget wtf.MultiSourceWidget
wtf.TextWidget wtf.TextWidget
app *tview.Application
GitRepos []*GitRepo GitRepos []*GitRepo
app *tview.Application
pages *tview.Pages pages *tview.Pages
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
MultiSourceWidget: wtf.NewMultiSourceWidget("git", "repository", "repositories"), MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common.ConfigKey, "repository", "repositories"),
TextWidget: wtf.NewTextWidget(app, "Git", "git", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
app: app, app: app,
pages: pages, pages: pages,
settings: settings,
} }
widget.LoadSources() widget.LoadSources()
@ -83,7 +86,7 @@ func (widget *Widget) Pull() {
} }
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
repoPaths := wtf.ToStrs(wtf.Config.UList("wtf.mods.git.repositories")) repoPaths := wtf.ToStrs(widget.settings.repositories)
widget.GitRepos = widget.gitRepos(repoPaths) widget.GitRepos = widget.gitRepos(repoPaths)
sort.Slice(widget.GitRepos, func(i, j int) bool { sort.Slice(widget.GitRepos, func(i, j int) bool {
@ -164,10 +167,16 @@ func (widget *Widget) gitRepos(repoPaths []string) []*GitRepo {
for _, repoPath := range repoPaths { for _, repoPath := range repoPaths {
if strings.HasSuffix(repoPath, "/") { if strings.HasSuffix(repoPath, "/") {
repos = append(repos, findGitRepositories(make([]*GitRepo, 0), repoPath)...) repos = append(repos, widget.findGitRepositories(make([]*GitRepo, 0), repoPath)...)
} else { } else {
repo := NewGitRepo(repoPath) repo := NewGitRepo(
repoPath,
widget.settings.commitCount,
widget.settings.commitFormat,
widget.settings.dateFormat,
)
repos = append(repos, repo) repos = append(repos, repo)
} }
} }
@ -175,7 +184,7 @@ func (widget *Widget) gitRepos(repoPaths []string) []*GitRepo {
return repos return repos
} }
func findGitRepositories(repositories []*GitRepo, directory string) []*GitRepo { func (widget *Widget) findGitRepositories(repositories []*GitRepo, directory string) []*GitRepo {
directory = strings.TrimSuffix(directory, "/") directory = strings.TrimSuffix(directory, "/")
files, err := ioutil.ReadDir(directory) files, err := ioutil.ReadDir(directory)
@ -188,16 +197,24 @@ func findGitRepositories(repositories []*GitRepo, directory string) []*GitRepo {
for _, file := range files { for _, file := range files {
if file.IsDir() { if file.IsDir() {
path = directory + "/" + file.Name() path = directory + "/" + file.Name()
if file.Name() == ".git" { if file.Name() == ".git" {
path = strings.TrimSuffix(path, "/.git") path = strings.TrimSuffix(path, "/.git")
repo := NewGitRepo(path)
repo := NewGitRepo(
path,
widget.settings.commitCount,
widget.settings.commitFormat,
widget.settings.dateFormat,
)
repositories = append(repositories, repo) repositories = append(repositories, repo)
continue continue
} }
if file.Name() == "vendor" || file.Name() == "node_modules" { if file.Name() == "vendor" || file.Name() == "node_modules" {
continue continue
} }
repositories = findGitRepositories(repositories, path) repositories = widget.findGitRepositories(repositories, path)
} }
} }

View File

@ -21,16 +21,16 @@ func (widget *Widget) display() {
str = str + widget.displayStats(repo) str = str + widget.displayStats(repo)
str = str + "\n" str = str + "\n"
str = str + " [red]Open Review Requests[white]\n" str = str + " [red]Open Review Requests[white]\n"
str = str + widget.displayMyReviewRequests(repo, wtf.Config.UString("wtf.mods.github.username")) str = str + widget.displayMyReviewRequests(repo, widget.settings.username)
str = str + "\n" str = str + "\n"
str = str + " [red]My Pull Requests[white]\n" str = str + " [red]My Pull Requests[white]\n"
str = str + widget.displayMyPullRequests(repo, wtf.Config.UString("wtf.mods.github.username")) str = str + widget.displayMyPullRequests(repo, widget.settings.username)
widget.View.SetText(str) widget.View.SetText(str)
} }
func (widget *Widget) displayMyPullRequests(repo *GithubRepo, username string) string { func (widget *Widget) displayMyPullRequests(repo *GithubRepo, username string) string {
prs := repo.myPullRequests(username) prs := repo.myPullRequests(username, widget.settings.enableStatus)
if len(prs) == 0 { if len(prs) == 0 {
return " [grey]none[white]\n" return " [grey]none[white]\n"
@ -38,7 +38,7 @@ func (widget *Widget) displayMyPullRequests(repo *GithubRepo, username string) s
str := "" str := ""
for _, pr := range prs { for _, pr := range prs {
str = str + fmt.Sprintf(" %s[green]%4d[white] %s\n", mergeString(pr), *pr.Number, *pr.Title) str = str + fmt.Sprintf(" %s[green]%4d[white] %s\n", widget.mergeString(pr), *pr.Number, *pr.Title)
} }
return str return str
@ -74,10 +74,6 @@ func (widget *Widget) title(repo *GithubRepo) string {
return fmt.Sprintf("[green]%s - %s[white]", repo.Owner, repo.Name) return fmt.Sprintf("[green]%s - %s[white]", repo.Owner, repo.Name)
} }
func showStatus() bool {
return wtf.Config.UBool("wtf.mods.github.enableStatus", false)
}
var mergeIcons = map[string]string{ var mergeIcons = map[string]string{
"dirty": "[red]![white] ", "dirty": "[red]![white] ",
"clean": "[green]✔[white] ", "clean": "[green]✔[white] ",
@ -85,8 +81,8 @@ var mergeIcons = map[string]string{
"blocked": "[red]✖[white] ", "blocked": "[red]✖[white] ",
} }
func mergeString(pr *github.PullRequest) string { func (widget *Widget) mergeString(pr *github.PullRequest) string {
if !showStatus() { if !widget.settings.enableStatus {
return "" return ""
} }
if str, ok := mergeIcons[pr.GetMergeableState()]; ok { if str, ok := mergeIcons[pr.GetMergeableState()]; ok {

View File

@ -3,7 +3,6 @@ package github
import ( import (
"context" "context"
"net/http" "net/http"
"os"
ghb "github.com/google/go-github/github" ghb "github.com/google/go-github/github"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
@ -21,13 +20,15 @@ type GithubRepo struct {
RemoteRepo *ghb.Repository RemoteRepo *ghb.Repository
} }
func NewGithubRepo(name, owner string) *GithubRepo { func NewGithubRepo(name, owner, apiKey, baseURL, uploadURL string) *GithubRepo {
repo := GithubRepo{ repo := GithubRepo{
Name: name, Name: name,
Owner: owner, Owner: owner,
}
repo.loadAPICredentials() apiKey: apiKey,
baseURL: baseURL,
uploadURL: uploadURL,
}
return &repo return &repo
} }
@ -94,25 +95,8 @@ func (repo *GithubRepo) githubClient() (*ghb.Client, error) {
return ghb.NewClient(oauthClient), nil return ghb.NewClient(oauthClient), nil
} }
func (repo *GithubRepo) loadAPICredentials() {
repo.apiKey = wtf.Config.UString(
"wtf.mods.github.apiKey",
os.Getenv("WTF_GITHUB_TOKEN"),
)
repo.baseURL = wtf.Config.UString(
"wtf.mods.github.baseURL",
os.Getenv("WTF_GITHUB_BASE_URL"),
)
repo.uploadURL = wtf.Config.UString(
"wtf.mods.github.uploadURL",
os.Getenv("WTF_GITHUB_UPLOAD_URL"),
)
}
// myPullRequests returns a list of pull requests created by username on this repo // myPullRequests returns a list of pull requests created by username on this repo
func (repo *GithubRepo) myPullRequests(username string) []*ghb.PullRequest { func (repo *GithubRepo) myPullRequests(username string, showStatus bool) []*ghb.PullRequest {
prs := []*ghb.PullRequest{} prs := []*ghb.PullRequest{}
for _, pr := range repo.PullRequests { for _, pr := range repo.PullRequests {
@ -123,7 +107,7 @@ func (repo *GithubRepo) myPullRequests(username string) []*ghb.PullRequest {
} }
} }
if showStatus() { if showStatus {
prs = repo.individualPRs(prs) prs = repo.individualPRs(prs)
} }

View File

@ -0,0 +1,38 @@
package github
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "github"
type Settings struct {
common *cfg.Common
apiKey string
baseURL string
enableStatus bool
repositories map[string]interface{}
uploadURL string
username string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_GITHUB_TOKEN")),
baseURL: localConfig.UString("baseURL", os.Getenv("WTF_GITHUB_BASE_URL")),
enableStatus: localConfig.UBool("enableStatus", false),
repositories: localConfig.UMap("repositories"),
uploadURL: localConfig.UString("uploadURL", os.Getenv("WTF_GITHUB_UPLOAD_URL")),
username: localConfig.UString("username"),
}
return &settings
}

View File

@ -26,17 +26,19 @@ type Widget struct {
GithubRepos []*GithubRepo GithubRepos []*GithubRepo
Idx int Idx int
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "GitHub", "github", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
Idx: 0, Idx: 0,
settings: settings,
} }
widget.GithubRepos = widget.buildRepoCollection(wtf.Config.UMap("wtf.mods.github.repositories")) widget.GithubRepos = widget.buildRepoCollection(widget.settings.repositories)
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.View.SetInputCapture(widget.keyboardIntercept) widget.View.SetInputCapture(widget.keyboardIntercept)
@ -78,7 +80,14 @@ func (widget *Widget) buildRepoCollection(repoData map[string]interface{}) []*Gi
githubRepos := []*GithubRepo{} githubRepos := []*GithubRepo{}
for name, owner := range repoData { for name, owner := range repoData {
repo := NewGithubRepo(name, owner.(string)) repo := NewGithubRepo(
name,
owner.(string),
widget.settings.apiKey,
widget.settings.baseURL,
widget.settings.uploadURL,
)
githubRepos = append(githubRepos, repo) githubRepos = append(githubRepos, repo)
} }

View File

@ -21,10 +21,10 @@ func (widget *Widget) display() {
str = str + widget.displayStats(project) str = str + widget.displayStats(project)
str = str + "\n" str = str + "\n"
str = str + " [red]Open Approval Requests[white]\n" str = str + " [red]Open Approval Requests[white]\n"
str = str + widget.displayMyApprovalRequests(project, wtf.Config.UString("wtf.mods.gitlab.username")) str = str + widget.displayMyApprovalRequests(project, widget.settings.username)
str = str + "\n" str = str + "\n"
str = str + " [red]My Merge Requests[white]\n" str = str + " [red]My Merge Requests[white]\n"
str = str + widget.displayMyMergeRequests(project, wtf.Config.UString("wtf.mods.gitlab.username")) str = str + widget.displayMyMergeRequests(project, widget.settings.username)
widget.View.SetText(str) widget.View.SetText(str)
} }

View File

@ -0,0 +1,34 @@
package gitlab
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "gitlab"
type Settings struct {
common *cfg.Common
apiKey string
domain string
projects map[string]interface{}
username string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_GITLAB_TOKEN")),
domain: localConfig.UString("domain"),
projects: localConfig.UMap("projects"),
username: localConfig.UString("username"),
}
return &settings
}

View File

@ -1,8 +1,6 @@
package gitlab package gitlab
import ( import (
"os"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
@ -25,15 +23,15 @@ type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
gitlab *glb.Client
GitlabProjects []*GitlabProject GitlabProjects []*GitlabProject
Idx int Idx int
gitlab *glb.Client
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
baseURL := wtf.Config.UString("wtf.mods.gitlab.domain") baseURL := settings.domain
gitlab := glb.NewClient(nil, apiKey()) gitlab := glb.NewClient(nil, settings.apiKey)
if baseURL != "" { if baseURL != "" {
gitlab.SetBaseURL(baseURL) gitlab.SetBaseURL(baseURL)
@ -41,14 +39,14 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Gitlab", "gitlab", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
gitlab: gitlab, Idx: 0,
gitlab: gitlab,
Idx: 0, settings: settings,
} }
widget.GitlabProjects = widget.buildProjectCollection(wtf.Config.UMap("wtf.mods.gitlab.projects")) widget.GitlabProjects = widget.buildProjectCollection(settings.projects)
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.View.SetInputCapture(widget.keyboardIntercept) widget.View.SetInputCapture(widget.keyboardIntercept)
@ -86,13 +84,6 @@ func (widget *Widget) Prev() {
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.gitlab.apiKey",
os.Getenv("WTF_GITLAB_TOKEN"),
)
}
func (widget *Widget) buildProjectCollection(projectData map[string]interface{}) []*GitlabProject { func (widget *Widget) buildProjectCollection(projectData map[string]interface{}) []*GitlabProject {
gitlabProjects := []*GitlabProject{} gitlabProjects := []*GitlabProject{}

View File

@ -5,18 +5,16 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/wtfutil/wtf/logger" "github.com/wtfutil/wtf/logger"
"github.com/wtfutil/wtf/wtf"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"strconv" "strconv"
) )
func GetMessages(roomId string, numberOfMessages int) ([]Message, error) { func GetMessages(roomId string, numberOfMessages int, apiToken string) ([]Message, error) {
var messages []Message var messages []Message
resp, err := apiRequest("rooms/" + roomId + "/chatMessages?limit=" + strconv.Itoa(numberOfMessages)) resp, err := apiRequest("rooms/"+roomId+"/chatMessages?limit="+strconv.Itoa(numberOfMessages), apiToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -26,10 +24,10 @@ func GetMessages(roomId string, numberOfMessages int) ([]Message, error) {
return messages, nil return messages, nil
} }
func GetRoom(roomUri string) (*Room, error) { func GetRoom(roomUri, apiToken string) (*Room, error) {
var rooms Rooms var rooms Rooms
resp, err := apiRequest("rooms?q=" + roomUri) resp, err := apiRequest("rooms?q="+roomUri, apiToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -52,9 +50,9 @@ var (
apiBaseURL = "https://api.gitter.im/v1/" apiBaseURL = "https://api.gitter.im/v1/"
) )
func apiRequest(path 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)
bearer := fmt.Sprintf("Bearer %s", apiToken()) bearer := fmt.Sprintf("Bearer %s", apiToken)
req.Header.Add("Authorization", bearer) req.Header.Add("Authorization", bearer)
httpClient := &http.Client{} httpClient := &http.Client{}
@ -86,10 +84,3 @@ func parseJson(obj interface{}, text io.Reader) {
} }
} }
} }
func apiToken() string {
return wtf.Config.UString(
"wtf.mods.gitter.apiToken",
os.Getenv("WTF_GITTER_API_TOKEN"),
)
}

View File

@ -0,0 +1,32 @@
package gitter
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "gitter"
type Settings struct {
common *cfg.Common
apiToken string
numberOfMessages int
roomURI string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiToken: localConfig.UString("apiToken", os.Getenv("WTF_GITTER_API_TOKEN")),
numberOfMessages: localConfig.UInt("numberOfMessages", 10),
roomURI: localConfig.UString("roomUri", "wtfutil/Lobby"),
}
return &settings
}

View File

@ -26,12 +26,15 @@ type Widget struct {
messages []Message messages []Message
selected int selected int
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Gitter", "gitter", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
@ -51,7 +54,7 @@ func (widget *Widget) Refresh() {
return return
} }
room, err := GetRoom(wtf.Config.UString("wtf.mods.gitter.roomUri", "wtfutil/Lobby")) room, err := GetRoom(widget.settings.roomURI, widget.settings.apiToken)
if err != nil { if err != nil {
widget.View.SetWrap(true) widget.View.SetWrap(true)
widget.View.SetTitle(widget.Name()) widget.View.SetTitle(widget.Name())
@ -63,7 +66,7 @@ func (widget *Widget) Refresh() {
return return
} }
messages, err := GetMessages(room.ID, wtf.Config.UInt("wtf.mods.gitter.numberOfMessages", 10)) messages, err := GetMessages(room.ID, widget.settings.numberOfMessages, widget.settings.apiToken)
if err != nil { if err != nil {
widget.View.SetWrap(true) widget.View.SetWrap(true)
@ -86,7 +89,7 @@ func (widget *Widget) display() {
widget.View.SetWrap(true) widget.View.SetWrap(true)
widget.View.Clear() widget.View.Clear()
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.Name(), wtf.Config.UString("wtf.mods.gitter.roomUri", "wtfutil/Lobby")))) widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.Name(), widget.settings.roomURI)))
widget.View.SetText(widget.contentFrom(widget.messages)) widget.View.SetText(widget.contentFrom(widget.messages))
widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight()
} }

View File

@ -26,10 +26,10 @@ import (
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func Fetch() ([]*sheets.ValueRange, error) { func (widget *Widget) Fetch() ([]*sheets.ValueRange, error) {
ctx := context.Background() ctx := context.Background()
secretPath, _ := wtf.ExpandHomeDir(wtf.Config.UString("wtf.mods.gspreadsheets.secretFile")) secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile)
b, err := ioutil.ReadFile(secretPath) b, err := ioutil.ReadFile(secretPath)
if err != nil { if err != nil {
@ -51,14 +51,13 @@ func Fetch() ([]*sheets.ValueRange, error) {
return nil, err return nil, err
} }
cells := wtf.ToStrs(wtf.Config.UList("wtf.mods.gspreadsheets.cells.addresses")) cells := wtf.ToStrs(widget.settings.cellAddresses)
documentId := wtf.Config.UString("wtf.mods.gspreadsheets.sheetId")
addresses := strings.Join(cells[:], ";") addresses := strings.Join(cells[:], ";")
responses := make([]*sheets.ValueRange, len(cells)) responses := make([]*sheets.ValueRange, len(cells))
for i := 0; i < len(cells); i++ { for i := 0; i < len(cells); i++ {
resp, err := srv.Spreadsheets.Values.Get(documentId, cells[i]).Do() resp, err := srv.Spreadsheets.Values.Get(widget.settings.sheetID, cells[i]).Do()
if err != nil { if err != nil {
log.Fatalf("Error fetching cells %s", addresses) log.Fatalf("Error fetching cells %s", addresses)
return nil, err return nil, err

View File

@ -0,0 +1,38 @@
package gspreadsheets
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "gspreadsheets"
type colors struct {
values string
}
type Settings struct {
colors
common *cfg.Common
cellAddresses []interface{}
cellNames []interface{}
secretFile string
sheetID string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
cellNames: localConfig.UList("cells.names"),
secretFile: localConfig.UString("secretFile"),
sheetID: localConfig.UString("sheetId"),
}
settings.colors.values = localConfig.UString("colors.values", "green")
return &settings
}

View File

@ -10,11 +10,15 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Google Spreadsheets", "gspreadsheets", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -23,7 +27,7 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
cells, _ := Fetch() cells, _ := widget.Fetch()
widget.View.SetText(widget.contentFrom(cells)) widget.View.SetText(widget.contentFrom(cells))
} }
@ -35,12 +39,11 @@ func (widget *Widget) contentFrom(valueRanges []*sheets.ValueRange) string {
return "error 1" return "error 1"
} }
valuesColor := wtf.Config.UString("wtf.mods.gspreadsheets.colors.values", "green")
res := "" res := ""
cells := wtf.ToStrs(wtf.Config.UList("wtf.mods.gspreadsheets.cells.names")) cells := wtf.ToStrs(widget.settings.cellNames)
for i := 0; i < len(valueRanges); i++ { for i := 0; i < len(valueRanges); i++ {
res = res + fmt.Sprintf("%s\t[%s]%s\n", cells[i], valuesColor, valueRanges[i].Values[0][0]) res = res + fmt.Sprintf("%s\t[%s]%s\n", cells[i], widget.settings.colors.values, valueRanges[i].Values[0][0])
} }
return res return res

View File

@ -0,0 +1,28 @@
package hackernews
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "hackernews"
type Settings struct {
common *cfg.Common
numberOfStories int
storyType string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
numberOfStories: localConfig.UInt("numberOfStories", 10),
storyType: localConfig.UString("storyType", "top"),
}
return &settings
}

View File

@ -32,12 +32,15 @@ type Widget struct {
stories []Story stories []Story
selected int selected int
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Hacker News", "hackernews", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
@ -57,7 +60,7 @@ func (widget *Widget) Refresh() {
return return
} }
storyIds, err := GetStories(wtf.Config.UString("wtf.mods.hackernews.storyType", "top")) storyIds, err := GetStories(widget.settings.storyType)
if storyIds == nil { if storyIds == nil {
return return
} }
@ -68,8 +71,7 @@ func (widget *Widget) Refresh() {
widget.View.SetText(err.Error()) widget.View.SetText(err.Error())
} else { } else {
var stories []Story var stories []Story
numberOfStoriesToDisplay := wtf.Config.UInt("wtf.mods.hackernews.numberOfStories", 10) for idx := 0; idx < widget.settings.numberOfStories; idx++ {
for idx := 0; idx < numberOfStoriesToDisplay; idx++ {
story, e := GetStory(storyIds[idx]) story, e := GetStory(storyIds[idx])
if e != nil { if e != nil {
panic(e) panic(e)
@ -94,7 +96,7 @@ func (widget *Widget) display() {
widget.View.SetWrap(false) widget.View.SetWrap(false)
widget.View.Clear() widget.View.Clear()
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %sstories", widget.Name(), wtf.Config.UString("wtf.mods.hackernews.storyType", "top")))) widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %sstories", widget.Name(), widget.settings.storyType)))
widget.View.SetText(widget.contentFrom(widget.stories)) widget.View.SetText(widget.contentFrom(widget.stories))
widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight()
} }

View File

@ -0,0 +1,31 @@
package ipapi
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "ipapi"
type colors struct {
name string
value string
}
type Settings struct {
colors
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
settings.colors.name = localConfig.UString("colors.name", "red")
settings.colors.value = localConfig.UString("colors.value", "white")
return &settings
}

View File

@ -15,10 +15,9 @@ import (
// Widget widget struct // Widget widget struct
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
result string
colors struct { result string
name, value string settings *Settings
}
} }
type ipinfo struct { type ipinfo struct {
@ -37,15 +36,15 @@ type ipinfo struct {
} }
// NewWidget constructor // NewWidget constructor
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "IPInfo", "ipapi", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
widget.View.SetWrap(false) widget.View.SetWrap(false)
widget.config()
return &widget return &widget
} }
@ -80,13 +79,6 @@ func (widget *Widget) ipinfo() {
widget.setResult(&info) widget.setResult(&info)
} }
// read module configs
func (widget *Widget) config() {
nameColor, valueColor := wtf.Config.UString("wtf.mods.ipinfo.colors.name", "red"), wtf.Config.UString("wtf.mods.ipinfo.colors.value", "white")
widget.colors.name = nameColor
widget.colors.value = valueColor
}
func (widget *Widget) setResult(info *ipinfo) { func (widget *Widget) setResult(info *ipinfo) {
resultTemplate, _ := template.New("ipinfo_result").Parse( resultTemplate, _ := template.New("ipinfo_result").Parse(
formatableText("IP Address", "Ip") + formatableText("IP Address", "Ip") +
@ -104,8 +96,8 @@ func (widget *Widget) setResult(info *ipinfo) {
resultBuffer := new(bytes.Buffer) resultBuffer := new(bytes.Buffer)
resultTemplate.Execute(resultBuffer, map[string]string{ resultTemplate.Execute(resultBuffer, map[string]string{
"nameColor": widget.colors.name, "nameColor": widget.settings.colors.name,
"valueColor": widget.colors.value, "valueColor": widget.settings.colors.value,
"Ip": info.Query, "Ip": info.Query,
"ISP": info.ISP, "ISP": info.ISP,
"AS": info.AS, "AS": info.AS,

View File

@ -0,0 +1,31 @@
package ipinfo
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "ipinfo"
type colors struct {
name string
value string
}
type Settings struct {
colors
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
settings.colors.name = localConfig.UString("colors.name", "red")
settings.colors.value = localConfig.UString("colors.value", "white")
return &settings
}

View File

@ -13,10 +13,9 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
result string
colors struct { result string
name, value string settings *Settings
}
} }
type ipinfo struct { type ipinfo struct {
@ -30,15 +29,15 @@ type ipinfo struct {
Organization string `json:"org"` Organization string `json:"org"`
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "IPInfo", "ipinfo", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
widget.View.SetWrap(false) widget.View.SetWrap(false)
widget.config()
return &widget return &widget
} }
@ -75,12 +74,6 @@ func (widget *Widget) ipinfo() {
widget.setResult(&info) widget.setResult(&info)
} }
// read module configs
func (widget *Widget) config() {
widget.colors.name = wtf.Config.UString("wtf.mods.ipinfo.colors.name", "white")
widget.colors.value = wtf.Config.UString("wtf.mods.ipinfo.colors.value", "white")
}
func (widget *Widget) setResult(info *ipinfo) { func (widget *Widget) setResult(info *ipinfo) {
resultTemplate, _ := template.New("ipinfo_result").Parse( resultTemplate, _ := template.New("ipinfo_result").Parse(
formatableText("IP", "Ip") + formatableText("IP", "Ip") +
@ -95,8 +88,8 @@ func (widget *Widget) setResult(info *ipinfo) {
resultBuffer := new(bytes.Buffer) resultBuffer := new(bytes.Buffer)
resultTemplate.Execute(resultBuffer, map[string]string{ resultTemplate.Execute(resultBuffer, map[string]string{
"nameColor": widget.colors.name, "nameColor": widget.settings.colors.name,
"valueColor": widget.colors.value, "valueColor": widget.settings.colors.value,
"Ip": info.Ip, "Ip": info.Ip,
"Hostname": info.Hostname, "Hostname": info.Hostname,
"City": info.City, "City": info.City,

View File

@ -9,11 +9,9 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"github.com/wtfutil/wtf/wtf"
) )
func Create(jenkinsURL string, username string, apiKey string) (*View, error) { func (widget *Widget) Create(jenkinsURL string, username string, apiKey string) (*View, error) {
const apiSuffix = "api/json?pretty=true" const apiSuffix = "api/json?pretty=true"
parsedSuffix, err := url.Parse(apiSuffix) parsedSuffix, err := url.Parse(apiSuffix)
if err != nil { if err != nil {
@ -29,10 +27,9 @@ func Create(jenkinsURL string, username string, apiKey string) (*View, error) {
req, _ := http.NewRequest("GET", jenkinsAPIURL.String(), nil) req, _ := http.NewRequest("GET", jenkinsAPIURL.String(), nil)
req.SetBasicAuth(username, apiKey) req.SetBasicAuth(username, apiKey)
verifyServerCertificate := wtf.Config.UBool("wtf.mods.jenkins.verifyServerCertificate", true)
httpClient := &http.Client{Transport: &http.Transport{ httpClient := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
InsecureSkipVerify: !verifyServerCertificate, InsecureSkipVerify: !widget.settings.verifyServerCertificate,
}, },
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
}, },

View File

@ -0,0 +1,38 @@
package jenkins
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "jenkins"
type Settings struct {
common *cfg.Common
apiKey string
jobNameRegex string
successBallColor string
url string
user string
verifyServerCertificate bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_JENKINS_API_KEY")),
jobNameRegex: localConfig.UString("jobNameRegex", ".*"),
successBallColor: localConfig.UString("successBallColor", "blue"),
url: localConfig.UString("url"),
user: localConfig.UString("user"),
verifyServerCertificate: localConfig.UBool("verifyServerCertificate", true),
}
return &settings
}

View File

@ -2,12 +2,12 @@ package jenkins
import ( import (
"fmt" "fmt"
"regexp" "strconv"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
"os" "regexp"
"strconv"
) )
const HelpText = ` const HelpText = `
@ -28,14 +28,17 @@ type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
view *View
selected int selected int
settings *Settings
view *View
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Jenkins", "jenkins", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
@ -55,10 +58,10 @@ func (widget *Widget) Refresh() {
return return
} }
view, err := Create( view, err := widget.Create(
wtf.Config.UString("wtf.mods.jenkins.url"), widget.settings.url,
wtf.Config.UString("wtf.mods.jenkins.user"), widget.settings.user,
widget.apiKey(), widget.settings.apiKey,
) )
widget.view = view widget.view = view
@ -86,18 +89,11 @@ func (widget *Widget) display() {
widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight()
} }
func (widget *Widget) apiKey() string {
return wtf.Config.UString(
"wtf.mods.jenkins.apiKey",
os.Getenv("WTF_JENKINS_API_KEY"),
)
}
func (widget *Widget) contentFrom(view *View) string { func (widget *Widget) contentFrom(view *View) string {
var str string var str string
for idx, job := range view.Jobs { for idx, job := range view.Jobs {
regex := wtf.Config.UString("wtf.mods.jenkins.jobNameRegex", ".*") var validID = regexp.MustCompile(widget.settings.jobNameRegex)
var validID = regexp.MustCompile(regex)
if validID.MatchString(job.Name) { if validID.MatchString(job.Name) {
str = str + fmt.Sprintf( str = str + fmt.Sprintf(
`["%d"][""][%s] [%s]%-6s[white]`, `["%d"][""][%s] [%s]%-6s[white]`,
@ -126,12 +122,7 @@ func (widget *Widget) jobColor(job *Job) string {
switch job.Color { switch job.Color {
case "blue": case "blue":
// Override color if successBallColor boolean param provided in config // Override color if successBallColor boolean param provided in config
ballColor := wtf.Config.UString("wtf.mods.jenkins.successBallColor", "blue") return widget.settings.successBallColor
if ballColor != "blue" {
return ballColor
} else {
return "blue"
}
case "red": case "red":
return "red" return "red"
default: default:

View File

@ -9,13 +9,10 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"os"
"strings" "strings"
"github.com/wtfutil/wtf/wtf"
) )
func IssuesFor(username string, projects []string, jql string) (*SearchResult, error) { func (widget *Widget) IssuesFor(username string, projects []string, jql string) (*SearchResult, error) {
query := []string{} query := []string{}
var projQuery = getProjectQuery(projects) var projQuery = getProjectQuery(projects)
@ -37,7 +34,7 @@ func IssuesFor(username string, projects []string, jql string) (*SearchResult, e
url := fmt.Sprintf("/rest/api/2/search?%s", v.Encode()) url := fmt.Sprintf("/rest/api/2/search?%s", v.Encode())
resp, err := jiraRequest(url) resp, err := widget.jiraRequest(url)
if err != nil { if err != nil {
return &SearchResult{}, err return &SearchResult{}, err
} }
@ -54,26 +51,18 @@ func buildJql(key string, value string) string {
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func apiKey() string { func (widget *Widget) jiraRequest(path string) (*http.Response, error) {
return wtf.Config.UString( url := fmt.Sprintf("%s%s", widget.settings.domain, path)
"wtf.mods.jira.apiKey",
os.Getenv("WTF_JIRA_API_KEY"),
)
}
func jiraRequest(path string) (*http.Response, error) {
url := fmt.Sprintf("%s%s", wtf.Config.UString("wtf.mods.jira.domain"), path)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req.SetBasicAuth(wtf.Config.UString("wtf.mods.jira.email"), apiKey()) req.SetBasicAuth(widget.settings.email, widget.settings.apiKey)
verifyServerCertificate := wtf.Config.UBool("wtf.mods.jira.verifyServerCertificate", true)
httpClient := &http.Client{Transport: &http.Transport{ httpClient := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
InsecureSkipVerify: !verifyServerCertificate, InsecureSkipVerify: !widget.settings.verifyServerCertificate,
}, },
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
}, },

76
modules/jira/settings.go Normal file
View File

@ -0,0 +1,76 @@
package jira
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "jira"
type colors struct {
rows struct {
even string
odd string
}
}
type Settings struct {
colors
common *cfg.Common
apiKey string
domain string
email string
jql string
projects []string
username string
verifyServerCertificate bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_JIRA_API_KEY")),
domain: localConfig.UString("domain"),
email: localConfig.UString("email"),
jql: localConfig.UString("jql"),
username: localConfig.UString("username"),
verifyServerCertificate: localConfig.UBool("verifyServerCertificate", true),
}
settings.colors.rows.even = localConfig.UString("colors.even", "lightblue")
settings.colors.rows.odd = localConfig.UString("colors.odd", "white")
settings.projects = settings.arrayifyProjects(localConfig)
return &settings
}
/* -------------------- Unexported functions -------------------- */
// arrayifyProjects figures out if we're dealing with a single project or an array of projects
func (settings *Settings) arrayifyProjects(localConfig *config.Config) []string {
projects := []string{}
// Single project
project, err := localConfig.String("project")
if err == nil {
projects = append(projects, project)
return projects
}
// Array of projects
projectList := localConfig.UList("project")
for _, projectName := range projectList {
if project, ok := projectName.(string); ok {
projects = append(projects, project)
}
}
return projects
}

View File

@ -28,12 +28,15 @@ type Widget struct {
result *SearchResult result *SearchResult
selected int selected int
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Jira", "jira", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
@ -48,10 +51,10 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
searchResult, err := IssuesFor( searchResult, err := widget.IssuesFor(
wtf.Config.UString("wtf.mods.jira.username"), widget.settings.username,
getProjects(), widget.settings.projects,
wtf.Config.UString("wtf.mods.jira.jql", ""), widget.settings.jql,
) )
if err != nil { if err != nil {
@ -74,7 +77,7 @@ func (widget *Widget) display() {
} }
widget.View.SetWrap(false) widget.View.SetWrap(false)
str := fmt.Sprintf("%s- [green]%s[white]", widget.Name(), wtf.Config.UString("wtf.mods.jira.project")) str := fmt.Sprintf("%s- [green]%s[white]", widget.Name(), widget.settings.projects)
widget.View.Clear() widget.View.Clear()
widget.View.SetTitle(widget.ContextualTitle(str)) widget.View.SetTitle(widget.ContextualTitle(str))
@ -100,7 +103,7 @@ func (widget *Widget) openItem() {
sel := widget.selected sel := widget.selected
if sel >= 0 && widget.result != nil && sel < len(widget.result.Issues) { if sel >= 0 && widget.result != nil && sel < len(widget.result.Issues) {
issue := &widget.result.Issues[widget.selected] issue := &widget.result.Issues[widget.selected]
wtf.OpenFile(wtf.Config.UString("wtf.mods.jira.domain") + "/browse/" + issue.Key) wtf.OpenFile(widget.settings.domain + "/browse/" + issue.Key)
} }
} }
@ -137,7 +140,12 @@ func (widget *Widget) rowColor(idx int) string {
if widget.View.HasFocus() && (idx == widget.selected) { if widget.View.HasFocus() && (idx == widget.selected) {
return wtf.DefaultFocussedRowColor() return wtf.DefaultFocussedRowColor()
} }
return wtf.RowColor("jira", idx)
if idx%2 == 0 {
return widget.settings.colors.rows.even
}
return widget.settings.colors.rows.odd
} }
func (widget *Widget) issueTypeColor(issue *Issue) string { func (widget *Widget) issueTypeColor(issue *Issue) string {
@ -153,24 +161,6 @@ func (widget *Widget) issueTypeColor(issue *Issue) string {
} }
} }
func getProjects() []string {
// see if project is set to a single string
configPath := "wtf.mods.jira.project"
singleProject, err := wtf.Config.String(configPath)
if err == nil {
return []string{singleProject}
}
// else, assume list
projList := wtf.Config.UList(configPath)
var ret []string
for _, proj := range projList {
if str, ok := proj.(string); ok {
ret = append(ret, str)
}
}
return ret
}
func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey { func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
switch string(event.Rune()) { switch string(event.Rune()) {
case "/": case "/":

View File

@ -19,13 +19,13 @@ type MercurialRepo struct {
Path string Path string
} }
func NewMercurialRepo(repoPath string) *MercurialRepo { func NewMercurialRepo(repoPath string, commitCount int, commitFormat string) *MercurialRepo {
repo := MercurialRepo{Path: repoPath} repo := MercurialRepo{Path: repoPath}
repo.Branch = strings.TrimSpace(repo.branch()) repo.Branch = strings.TrimSpace(repo.branch())
repo.Bookmark = strings.TrimSpace(repo.bookmark()) repo.Bookmark = strings.TrimSpace(repo.bookmark())
repo.ChangedFiles = repo.changedFiles() repo.ChangedFiles = repo.changedFiles()
repo.Commits = repo.commits() repo.Commits = repo.commits(commitCount, commitFormat)
repo.Repository = strings.TrimSpace(repo.Path) repo.Repository = strings.TrimSpace(repo.Path)
return &repo return &repo
@ -61,10 +61,8 @@ func (repo *MercurialRepo) changedFiles() []string {
return data return data
} }
func (repo *MercurialRepo) commits() []string { func (repo *MercurialRepo) commits(commitCount int, commitFormat string) []string {
numStr := fmt.Sprintf("-l %d", wtf.Config.UInt("wtf.mods.mercurial.commitCount", 10)) numStr := fmt.Sprintf("-l %d", commitCount)
commitFormat := wtf.Config.UString("wtf.mods.mercurial.commitFormat", "[forestgreen]{rev}:{phase} [white]{desc|firstline|strip} [grey]{author|person} {date|age}[white]")
commitStr := fmt.Sprintf("--template=\"%s\n\"", commitFormat) commitStr := fmt.Sprintf("--template=\"%s\n\"", commitFormat)
arg := []string{"log", repo.repoPath(), numStr, commitStr} arg := []string{"log", repo.repoPath(), numStr, commitStr}

View File

@ -0,0 +1,30 @@
package mercurial
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "mercurial"
type Settings struct {
common *cfg.Common
commitCount int
commitFormat string
repositories []interface{}
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
commitCount: localConfig.UInt("commitCount", 10),
commitFormat: localConfig.UString("commitFormat", "[forestgreen]{rev}:{phase} [white]{desc|firstline|strip} [grey]{author|person} {date|age}[white]"),
repositories: localConfig.UList("repositories"),
}
return &settings
}

View File

@ -28,19 +28,21 @@ type Widget struct {
wtf.MultiSourceWidget wtf.MultiSourceWidget
wtf.TextWidget wtf.TextWidget
app *tview.Application app *tview.Application
Data []*MercurialRepo Data []*MercurialRepo
pages *tview.Pages pages *tview.Pages
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
MultiSourceWidget: wtf.NewMultiSourceWidget("mercurial", "repository", "repositories"), MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common.ConfigKey, "repository", "repositories"),
TextWidget: wtf.NewTextWidget(app, "Mercurial", "mercurial", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
app: app, app: app,
pages: pages, pages: pages,
settings: settings,
} }
widget.LoadSources() widget.LoadSources()
@ -79,7 +81,7 @@ func (widget *Widget) Pull() {
} }
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
repoPaths := wtf.ToStrs(wtf.Config.UList("wtf.mods.mercurial.repositories")) repoPaths := wtf.ToStrs(widget.settings.repositories)
widget.Data = widget.mercurialRepos(repoPaths) widget.Data = widget.mercurialRepos(repoPaths)
widget.display() widget.display()
@ -156,7 +158,7 @@ func (widget *Widget) mercurialRepos(repoPaths []string) []*MercurialRepo {
repos := []*MercurialRepo{} repos := []*MercurialRepo{}
for _, repoPath := range repoPaths { for _, repoPath := range repoPaths {
repo := NewMercurialRepo(repoPath) repo := NewMercurialRepo(repoPath, widget.settings.commitCount, widget.settings.commitFormat)
repos = append(repos, repo) repos = append(repos, repo)
} }

View File

@ -0,0 +1,20 @@
package nbascore
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "nbascore"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -22,22 +22,23 @@ const HelpText = `
type Widget struct { type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
app *tview.Application
pages *tview.Pages
language string language string
result string result string
settings *Settings
} }
var offset = 0 var offset = 0
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "NBA Score", "nbascore", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.TextWidget.RefreshInt = 15
widget.View.SetInputCapture(widget.keyboardIntercept) widget.View.SetInputCapture(widget.keyboardIntercept)
widget.View.SetScrollable(true) widget.View.SetScrollable(true)

View File

@ -0,0 +1,32 @@
package newrelic
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "newrelic"
type Settings struct {
common *cfg.Common
apiKey string
applicationID int
deployCount int
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_NEW_RELIC_API_KEY")),
applicationID: localConfig.UInt("applicationID"),
deployCount: localConfig.UInt("deployCount", 5),
}
return &settings
}

View File

@ -2,7 +2,6 @@ package newrelic
import ( import (
"fmt" "fmt"
"os"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf" "github.com/wtfutil/wtf/wtf"
@ -11,15 +10,20 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
client *Client
client *Client
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "New Relic", "newrelic", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
client: NewClient(apiKey(), wtf.Config.UInt("wtf.mods.newrelic.applicationId")),
settings: settings,
} }
widget.client = NewClient(widget.settings.apiKey, widget.settings.applicationID)
return &widget return &widget
} }
@ -81,7 +85,7 @@ func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string {
revisions = append(revisions, deploy.Revision) revisions = append(revisions, deploy.Revision)
if len(revisions) == wtf.Config.UInt("wtf.mods.newrelic.deployCount", 5) { if len(revisions) == widget.settings.deployCount {
break break
} }
} }
@ -89,10 +93,3 @@ func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string {
return str return str
} }
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.newrelic.apiKey",
os.Getenv("WTF_NEW_RELIC_API_KEY"),
)
}

View File

@ -4,9 +4,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"os"
"github.com/wtfutil/wtf/wtf"
) )
type OnCallResponse struct { type OnCallResponse struct {
@ -29,11 +26,12 @@ type Parent struct {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse, error) { func (widget *Widget) Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse, error) {
agregatedResponses := []*OnCallResponse{} agregatedResponses := []*OnCallResponse{}
for _, sched := range schedules { for _, sched := range schedules {
scheduleUrl := fmt.Sprintf("https://api.opsgenie.com/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", sched, scheduleIdentifierType) scheduleUrl := fmt.Sprintf("https://api.opsgenie.com/v2/schedules/%s/on-calls?scheduleIdentifierType=%s&flat=true", sched, scheduleIdentifierType)
response, err := opsGenieRequest(scheduleUrl, 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
@ -44,13 +42,6 @@ func Fetch(scheduleIdentifierType string, schedules []string) ([]*OnCallResponse
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.opsgenie.apiKey",
os.Getenv("WTF_OPS_GENIE_API_KEY"),
)
}
func opsGenieRequest(url string, apiKey string) (*OnCallResponse, error) { func opsGenieRequest(url string, apiKey string) (*OnCallResponse, error) {
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {

View File

@ -0,0 +1,57 @@
package opsgenie
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "opsgenie"
type Settings struct {
common *cfg.Common
apiKey string
displayEmpty bool
schedule []string
scheduleIdentifierType string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_OPS_GENIE_API_KEY")),
displayEmpty: localConfig.UBool("displayEmpty", true),
scheduleIdentifierType: localConfig.UString("scheduleIdentifierType", "id"),
}
settings.schedule = settings.arrayifySchedules(localConfig)
return &settings
}
// arrayifySchedules figures out if we're dealing with a single project or an array of projects
func (settings *Settings) arrayifySchedules(localConfig *config.Config) []string {
schedules := []string{}
// Single schedule
schedule, err := localConfig.String("schedule")
if err == nil {
schedules = append(schedules, schedule)
return schedules
}
// Array of schedules
scheduleList := localConfig.UList("schedule")
for _, scheduleName := range scheduleList {
if schedule, ok := scheduleName.(string); ok {
schedules = append(schedules, schedule)
}
}
return schedules
}

View File

@ -10,11 +10,15 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "OpsGenie", "opsgenie", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -23,10 +27,11 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
data, err := Fetch( data, err := widget.Fetch(
wtf.Config.UString("wtf.mods.opsgenie.scheduleIdentifierType"), widget.settings.scheduleIdentifierType,
getSchedules(), widget.settings.schedule,
) )
widget.View.SetTitle(widget.ContextualTitle(widget.Name())) widget.View.SetTitle(widget.ContextualTitle(widget.Name()))
var content string var content string
@ -43,31 +48,11 @@ func (widget *Widget) Refresh() {
/* -------------------- Unexported Functions -------------------- */ /* -------------------- Unexported Functions -------------------- */
func getSchedules() []string {
// see if schedule is set to a single string
configPath := "wtf.mods.opsgenie.schedule"
singleSchedule, err := wtf.Config.String(configPath)
if err == nil {
return []string{singleSchedule}
}
// else, assume list
scheduleList := wtf.Config.UList(configPath)
var ret []string
for _, schedule := range scheduleList {
if str, ok := schedule.(string); ok {
ret = append(ret, str)
}
}
return ret
}
func (widget *Widget) contentFrom(onCallResponses []*OnCallResponse) string { func (widget *Widget) contentFrom(onCallResponses []*OnCallResponse) string {
str := "" str := ""
displayEmpty := wtf.Config.UBool("wtf.mods.opsgenie.displayEmpty", true)
for _, data := range onCallResponses { for _, data := range onCallResponses {
if (len(data.OnCallData.Recipients) == 0) && (displayEmpty == false) { if (len(data.OnCallData.Recipients) == 0) && (widget.settings.displayEmpty == false) {
continue continue
} }

View File

@ -1,16 +1,14 @@
package pagerduty package pagerduty
import ( import (
"os"
"time" "time"
"github.com/PagerDuty/go-pagerduty" "github.com/PagerDuty/go-pagerduty"
"github.com/wtfutil/wtf/wtf"
) )
// GetOnCalls returns a list of people currently on call // GetOnCalls returns a list of people currently on call
func GetOnCalls() ([]pagerduty.OnCall, error) { func GetOnCalls(apiKey string) ([]pagerduty.OnCall, error) {
client := pagerduty.NewClient(apiKey()) client := pagerduty.NewClient(apiKey)
var results []pagerduty.OnCall var results []pagerduty.OnCall
@ -38,8 +36,8 @@ func GetOnCalls() ([]pagerduty.OnCall, error) {
} }
// GetIncidents returns a list of people currently on call // GetIncidents returns a list of people currently on call
func GetIncidents() ([]pagerduty.Incident, error) { func GetIncidents(apiKey string) ([]pagerduty.Incident, error) {
client := pagerduty.NewClient(apiKey()) client := pagerduty.NewClient(apiKey)
var results []pagerduty.Incident var results []pagerduty.Incident
@ -64,10 +62,3 @@ func GetIncidents() ([]pagerduty.Incident, error) {
return results, nil return results, nil
} }
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.pagerduty.apiKey",
os.Getenv("WTF_PAGERDUTY_API_KEY"),
)
}

View File

@ -0,0 +1,34 @@
package pagerduty
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "pagerduty"
type Settings struct {
common *cfg.Common
apiKey string
escalationFilter []interface{}
showIncidents bool
showSchedules bool
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
apiKey: localConfig.UString("apiKey", os.Getenv("WTF_PAGERDUTY_API_KEY")),
escalationFilter: localConfig.UList("escalationFilter"),
showIncidents: localConfig.UBool("showIncidents", true),
showSchedules: localConfig.UBool("showSchedules", true),
}
return &settings
}

View File

@ -11,11 +11,15 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "PagerDuty", "pagerduty", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -30,12 +34,12 @@ func (widget *Widget) Refresh() {
var err1 error var err1 error
var err2 error var err2 error
if wtf.Config.UBool("wtf.mods.pagerduty.showSchedules", true) { if widget.settings.showSchedules {
onCalls, err1 = GetOnCalls() onCalls, err1 = GetOnCalls(widget.settings.apiKey)
} }
if wtf.Config.UBool("wtf.mods.pagerduty.showIncidents") { if widget.settings.showIncidents {
incidents, err2 = GetIncidents() incidents, err2 = GetIncidents(widget.settings.apiKey)
} }
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s", widget.Name()))) widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s", widget.Name())))
@ -75,15 +79,14 @@ func (widget *Widget) contentFrom(onCalls []pagerduty.OnCall, incidents []pagerd
tree := make(map[string][]pagerduty.OnCall) tree := make(map[string][]pagerduty.OnCall)
filtering := wtf.Config.UList("wtf.mods.pagerduty.escalationFilter")
filter := make(map[string]bool) filter := make(map[string]bool)
for _, item := range filtering { for _, item := range widget.settings.escalationFilter {
filter[item.(string)] = true filter[item.(string)] = true
} }
for _, onCall := range onCalls { for _, onCall := range onCalls {
key := onCall.EscalationPolicy.Summary key := onCall.EscalationPolicy.Summary
if len(filtering) == 0 || filter[key] { if len(widget.settings.escalationFilter) == 0 || filter[key] {
tree[key] = append(tree[key], onCall) tree[key] = append(tree[key], onCall)
} }
} }

22
modules/power/settings.go Normal file
View File

@ -0,0 +1,22 @@
package power
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "power"
type Settings struct {
common *cfg.Common
filePath string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -10,13 +10,16 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
Battery *Battery Battery *Battery
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Power", "power", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
Battery: NewBattery(),
Battery: NewBattery(),
settings: settings,
} }
widget.View.SetWrap(true) widget.View.SetWrap(true)

View File

@ -0,0 +1,20 @@
package resourceusage
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "resourceusage"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -17,12 +17,16 @@ var ok = true
// Widget define wtf widget to register widget later // Widget define wtf widget to register widget later
type Widget struct { type Widget struct {
wtf.BarGraph wtf.BarGraph
settings *Settings
} }
// NewWidget Make new instance of widget // NewWidget Make new instance of widget
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
BarGraph: wtf.NewBarGraph(app, "Resource Usage", "resourceusage", false), BarGraph: wtf.NewBarGraph(app, settings.common.Name, settings.common.ConfigKey, false),
settings: settings,
} }
widget.View.SetWrap(false) widget.View.SetWrap(false)

View File

@ -8,17 +8,14 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"github.com/wtfutil/wtf/wtf"
) )
func CurrentActiveItems() (*ActiveItems, error) { func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*ActiveItems, error) {
items := &ActiveItems{} items := &ActiveItems{}
accessToken := wtf.Config.UString("wtf.mods.rollbar.accessToken", "")
rollbarAPIURL.Host = "api.rollbar.com" rollbarAPIURL.Host = "api.rollbar.com"
rollbarAPIURL.Path = "/api/1/items" rollbarAPIURL.Path = "/api/1/items"
resp, err := rollbarItemRequest(accessToken) resp, err := rollbarItemRequest(accessToken, assignedToName, activeOnly)
if err != nil { if err != nil {
return items, err return items, err
} }
@ -34,13 +31,11 @@ var (
rollbarAPIURL = &url.URL{Scheme: "https"} rollbarAPIURL = &url.URL{Scheme: "https"}
) )
func rollbarItemRequest(accessToken string) (*http.Response, error) { func rollbarItemRequest(accessToken, assignedToName string, activeOnly bool) (*http.Response, error) {
params := url.Values{} params := url.Values{}
params.Add("access_token", accessToken) params.Add("access_token", accessToken)
userName := wtf.Config.UString("wtf.mods.rollbar.assignedToName", "") params.Add("assigned_user", assignedToName)
params.Add("assigned_user", userName) if activeOnly {
active := wtf.Config.UBool("wtf.mods.rollbar.activeOnly", false)
if active {
params.Add("status", "active") params.Add("status", "active")
} }

View File

@ -0,0 +1,36 @@
package rollbar
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "rollbar"
type Settings struct {
common *cfg.Common
accessToken string
activeOnly bool
assignedToName string
count int
projectName string
projectOwner string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
accessToken: localConfig.UString("accessToken"),
activeOnly: localConfig.UBool("activeOnly", false),
assignedToName: localConfig.UString("assignedToName"),
count: localConfig.UInt("count", 10),
projectName: localConfig.UString("projectName", "Items"),
projectOwner: localConfig.UString("projectOwner"),
}
return &settings
}

View File

@ -29,13 +29,17 @@ type Widget struct {
items *Result items *Result
selected int selected int
settings *Settings
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Rollbar", "rollbar", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
settings: settings,
} }
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.unselect() widget.unselect()
@ -51,7 +55,11 @@ func (widget *Widget) Refresh() {
return return
} }
items, err := CurrentActiveItems() items, err := CurrentActiveItems(
widget.settings.accessToken,
widget.settings.assignedToName,
widget.settings.activeOnly,
)
if err != nil { if err != nil {
widget.View.SetWrap(true) widget.View.SetWrap(true)
@ -72,16 +80,14 @@ func (widget *Widget) display() {
} }
widget.View.SetWrap(false) widget.View.SetWrap(false)
projectName := wtf.Config.UString("wtf.mods.rollbar.projectName", "Items") widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.Name(), widget.settings.projectName)))
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.Name(), projectName)))
widget.View.SetText(widget.contentFrom(widget.items)) widget.View.SetText(widget.contentFrom(widget.items))
} }
func (widget *Widget) contentFrom(result *Result) string { func (widget *Widget) contentFrom(result *Result) string {
var str string var str string
count := wtf.Config.UInt("wtf.mods.rollbar.count", 10) if len(result.Items) > widget.settings.count {
if len(result.Items) > count { result.Items = result.Items[:widget.settings.count]
result.Items = result.Items[:count]
} }
for idx, item := range result.Items { for idx, item := range result.Items {
@ -151,12 +157,18 @@ func (widget *Widget) prev() {
} }
func (widget *Widget) openBuild() { func (widget *Widget) openBuild() {
sel := widget.selected if widget.selected >= 0 && widget.items != nil && widget.selected < len(widget.items.Items) {
projectOwner := wtf.Config.UString("wtf.mods.rollbar.projectOwner", "")
projectName := wtf.Config.UString("wtf.mods.rollbar.projectName", "")
if sel >= 0 && widget.items != nil && sel < len(widget.items.Items) {
item := &widget.items.Items[widget.selected] item := &widget.items.Items[widget.selected]
wtf.OpenFile(fmt.Sprintf("https://rollbar.com/%s/%s/%s/%d", projectOwner, projectName, "items", item.ID))
wtf.OpenFile(
fmt.Sprintf(
"https://rollbar.com/%s/%s/%s/%d",
widget.settings.projectOwner,
widget.settings.projectName,
"items",
item.ID,
),
)
} }
} }

View File

@ -0,0 +1,20 @@
package security
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "security"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -10,11 +10,15 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Security", "security", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
settings: settings,
} }
return &widget return &widget
@ -48,12 +52,10 @@ func (widget *Widget) contentFrom(data *SecurityData) string {
str = str + "\n" str = str + "\n"
str = str + " [red]Users[white]\n" str = str + " [red]Users[white]\n"
str = str + fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, "\n ")) str = str + fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, "\n "))
str = str + "\n" str = str + "\n\n"
str = str + " [red]DNS[white]\n" str = str + " [red]DNS[white]\n"
//str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Enabled", widget.labelColor(data.FirewallEnabled), data.FirewallEnabled, data.DnsAt(0))
//str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Stealth", widget.labelColor(data.FirewallStealth), data.FirewallStealth, data.DnsAt(1))
str = str + fmt.Sprintf(" %12s\n", data.DnsAt(0)) str = str + fmt.Sprintf(" %12s\n", data.DnsAt(0))
str = str + fmt.Sprintf(" %12s\n", data.DnsAt(1)) str = str + fmt.Sprintf(" %12s\n", data.DnsAt(1))
str = str + "\n" str = str + "\n"

View File

@ -0,0 +1,20 @@
package spotify
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "spotify"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -20,20 +20,26 @@ const HelpText = `
type Widget struct { type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
spotigopher.SpotifyClient
settings *Settings
spotigopher.Info spotigopher.Info
spotigopher.SpotifyClient
} }
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
spotifyClient := spotigopher.NewClient() spotifyClient := spotigopher.NewClient()
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "Spotify", "spotify", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
SpotifyClient: spotifyClient,
Info: spotigopher.Info{}, Info: spotigopher.Info{},
SpotifyClient: spotifyClient,
settings: settings,
} }
widget.settings.common.RefreshInterval = 5
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.TextWidget.RefreshInt = 5
widget.View.SetInputCapture(widget.captureInput) widget.View.SetInputCapture(widget.captureInput)
widget.View.SetWrap(true) widget.View.SetWrap(true)
widget.View.SetWordWrap(true) widget.View.SetWordWrap(true)

View File

@ -0,0 +1,32 @@
package spotifyweb
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "spotifyweb"
type Settings struct {
common *cfg.Common
callbackPort string
clientID string
secretKey string
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
localConfig, _ := ymlConfig.Get("wtf.mods." + configKey)
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
callbackPort: localConfig.UString("callbackPort", "8080"),
clientID: localConfig.UString("clientID", os.Getenv("SPOTIFY_ID")),
secretKey: localConfig.UString("secretKey", os.Getenv("SPOTIFY_SECRET")),
}
return &settings
}

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"os"
"time" "time"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
@ -47,10 +46,12 @@ type Info struct {
type Widget struct { type Widget struct {
wtf.HelpfulWidget wtf.HelpfulWidget
wtf.TextWidget wtf.TextWidget
Info Info
clientChan chan *spotify.Client
client *spotify.Client client *spotify.Client
clientChan chan *spotify.Client
playerState *spotify.PlayerState playerState *spotify.PlayerState
settings *Settings
} }
var ( var (
@ -79,27 +80,12 @@ func authHandler(w http.ResponseWriter, r *http.Request) {
tempClientChan <- &client tempClientChan <- &client
} }
func clientID() string {
return wtf.Config.UString(
"wtf.mods.spotifyweb.clientID",
os.Getenv("SPOTIFY_ID"),
)
}
func secretKey() string {
return wtf.Config.UString(
"wtf.mods.spotifyweb.secretKey",
os.Getenv("SPOTIFY_SECRET"),
)
}
// NewWidget creates a new widget for WTF // NewWidget creates a new widget for WTF
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
callbackPort = wtf.Config.UString("wtf.mods.spotifyweb.callbackPort", "8080") redirectURI = "http://localhost:" + settings.callbackPort + "/callback"
redirectURI = "http://localhost:" + callbackPort + "/callback"
auth = spotify.NewAuthenticator(redirectURI, spotify.ScopeUserReadCurrentlyPlaying, spotify.ScopeUserReadPlaybackState, spotify.ScopeUserModifyPlaybackState) auth = spotify.NewAuthenticator(redirectURI, spotify.ScopeUserReadCurrentlyPlaying, spotify.ScopeUserReadPlaybackState, spotify.ScopeUserModifyPlaybackState)
auth.SetAuthInfo(clientID(), secretKey()) auth.SetAuthInfo(settings.clientID, settings.secretKey)
authURL = auth.AuthURL(state) authURL = auth.AuthURL(state)
var client *spotify.Client var client *spotify.Client
@ -107,11 +93,13 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
widget := Widget{ widget := Widget{
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
TextWidget: wtf.NewTextWidget(app, "SpotifyWeb", "spotifyweb", true), TextWidget: wtf.NewTextWidget(app, settings.common, true),
Info: Info{},
clientChan: tempClientChan, Info: Info{},
client: client, client: client,
playerState: playerState, clientChan: tempClientChan,
playerState: playerState,
settings: settings,
} }
http.HandleFunc("/callback", authHandler) http.HandleFunc("/callback", authHandler)
@ -147,8 +135,9 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
// If inconvenient, I'll remove this option and save the URL in a file or some other method. // If inconvenient, I'll remove this option and save the URL in a file or some other method.
wtf.OpenFile(`"` + authURL + `"`) wtf.OpenFile(`"` + authURL + `"`)
widget.settings.common.RefreshInterval = 5
widget.HelpfulWidget.SetView(widget.View) widget.HelpfulWidget.SetView(widget.View)
widget.TextWidget.RefreshInt = 5
widget.View.SetInputCapture(widget.captureInput) widget.View.SetInputCapture(widget.captureInput)
widget.View.SetWrap(true) widget.View.SetWrap(true)
widget.View.SetWordWrap(true) widget.View.SetWordWrap(true)

View File

@ -0,0 +1,20 @@
package status
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "status"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -9,12 +9,15 @@ type Widget struct {
wtf.TextWidget wtf.TextWidget
CurrentIcon int CurrentIcon int
settings *Settings
} }
func NewWidget(app *tview.Application) *Widget { func NewWidget(app *tview.Application, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Status", "status", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
CurrentIcon: 0, CurrentIcon: 0,
settings: settings,
} }
return &widget return &widget

View File

@ -0,0 +1,20 @@
package system
import (
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const configKey = "system"
type Settings struct {
common *cfg.Common
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromYAML(name, configKey, ymlConfig),
}
return &settings
}

View File

@ -11,17 +11,19 @@ import (
type Widget struct { type Widget struct {
wtf.TextWidget wtf.TextWidget
systemInfo *SystemInfo
Date string Date string
Version string Version string
settings *Settings
systemInfo *SystemInfo
} }
func NewWidget(app *tview.Application, date, version string) *Widget { func NewWidget(app *tview.Application, date, version string, settings *Settings) *Widget {
widget := Widget{ widget := Widget{
TextWidget: wtf.NewTextWidget(app, "System", "system", false), TextWidget: wtf.NewTextWidget(app, settings.common, false),
Date: date, Date: date,
Version: version, settings: settings,
Version: version,
} }
widget.systemInfo = NewSystemInfo() widget.systemInfo = NewSystemInfo()

Some files were not shown because too many files have changed in this diff Show More