mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Merge branch 'master' into add_digitalclock_module
This commit is contained in:
163
modules/docker/client.go
Normal file
163
modules/docker/client.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (widget *Widget) getSystemInfo() string {
|
||||
info, err := widget.cli.Info(context.Background())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get docker system info").Error()
|
||||
}
|
||||
|
||||
diskUsage, err := widget.cli.DiskUsage(context.Background())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get disk usage").Error()
|
||||
}
|
||||
|
||||
var duContainer int64
|
||||
for _, c := range diskUsage.Containers {
|
||||
duContainer += c.SizeRw
|
||||
}
|
||||
var duImg int64
|
||||
for _, im := range diskUsage.Images {
|
||||
duImg += im.Size
|
||||
}
|
||||
var duVol int64
|
||||
for _, v := range diskUsage.Volumes {
|
||||
duVol += v.UsageData.Size
|
||||
}
|
||||
|
||||
sysInfo := []struct {
|
||||
name string
|
||||
value string
|
||||
}{
|
||||
{
|
||||
name: "name:",
|
||||
value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.Name),
|
||||
}, {
|
||||
name: "version:",
|
||||
value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.ServerVersion),
|
||||
}, {
|
||||
name: "root:",
|
||||
value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.DockerRootDir),
|
||||
},
|
||||
{
|
||||
name: "containers:",
|
||||
value: fmt.Sprintf("[lime]%d[white]/[yellow]%d[white]/[red]%d",
|
||||
info.ContainersRunning,
|
||||
info.ContainersPaused, info.ContainersStopped),
|
||||
},
|
||||
{
|
||||
name: "images:",
|
||||
value: fmt.Sprintf("[%s]%d", widget.settings.common.Foreground, info.Images),
|
||||
},
|
||||
{
|
||||
name: "volumes:",
|
||||
value: fmt.Sprintf("[%s]%v", widget.settings.common.Foreground, len(diskUsage.Volumes)),
|
||||
},
|
||||
{
|
||||
name: "memory limit:",
|
||||
value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, humanize.Bytes(uint64(info.MemTotal))),
|
||||
},
|
||||
{
|
||||
name: "disk usage:",
|
||||
value: fmt.Sprintf(`
|
||||
[%s]* containers: [%s]%s
|
||||
[%s]* images: [%s]%s
|
||||
[%s]* volumes: [%s]%s
|
||||
[%s]* [::b]total: [%s]%s[::-]
|
||||
`,
|
||||
widget.settings.labelColor,
|
||||
widget.settings.common.Foreground,
|
||||
humanize.Bytes(uint64(duContainer)),
|
||||
|
||||
widget.settings.labelColor,
|
||||
widget.settings.common.Foreground,
|
||||
humanize.Bytes(uint64(duImg)),
|
||||
|
||||
widget.settings.labelColor,
|
||||
widget.settings.common.Foreground,
|
||||
humanize.Bytes(uint64(duVol)),
|
||||
|
||||
widget.settings.labelColor,
|
||||
widget.settings.common.Foreground,
|
||||
humanize.Bytes(uint64(duContainer+duImg+duVol))),
|
||||
},
|
||||
}
|
||||
|
||||
padSlice(true, sysInfo, func(i int) string {
|
||||
return sysInfo[i].name
|
||||
}, func(i int, newVal string) {
|
||||
sysInfo[i].name = newVal
|
||||
})
|
||||
|
||||
result := ""
|
||||
for _, info := range sysInfo {
|
||||
result += fmt.Sprintf("[%s]%s %s\n", widget.settings.labelColor, info.name, info.value)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (widget *Widget) getContainerStates() string {
|
||||
cntrs, err := widget.cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get container list").Error()
|
||||
}
|
||||
|
||||
if len(cntrs) == 0 {
|
||||
return "no containers"
|
||||
}
|
||||
|
||||
colorMap := map[string]string{
|
||||
"created": "green",
|
||||
"running": "lime",
|
||||
"paused": "yellow",
|
||||
"restarting": "yellow",
|
||||
"removing": "yellow",
|
||||
"exited": "red",
|
||||
"dead": "red",
|
||||
}
|
||||
|
||||
containers := []struct {
|
||||
name string
|
||||
state string
|
||||
}{}
|
||||
for _, c := range cntrs {
|
||||
container := struct {
|
||||
name string
|
||||
state string
|
||||
}{
|
||||
name: c.Names[0],
|
||||
state: c.State,
|
||||
}
|
||||
|
||||
container.name = strings.Replace(container.name, "/", "", -1)
|
||||
containers = append(containers, container)
|
||||
}
|
||||
|
||||
sort.Slice(containers, func(i, j int) bool {
|
||||
return containers[i].name < containers[j].name
|
||||
})
|
||||
|
||||
padSlice(false, containers, func(i int) string {
|
||||
return containers[i].name
|
||||
}, func(i int, val string) {
|
||||
containers[i].name = val
|
||||
})
|
||||
|
||||
result := ""
|
||||
for _, c := range containers {
|
||||
result += fmt.Sprintf("[white]%s [%s]%s\n", c.name, colorMap[c.state], c.state)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
37
modules/docker/example-conf.yml
Normal file
37
modules/docker/example-conf.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
wtf:
|
||||
colors:
|
||||
# background: black
|
||||
# foreground: blue
|
||||
border:
|
||||
focusable: darkslateblue
|
||||
focused: orange
|
||||
normal: gray
|
||||
checked: yellow
|
||||
highlight:
|
||||
fore: black
|
||||
back: gray
|
||||
rows:
|
||||
even: yellow
|
||||
odd: white
|
||||
grid:
|
||||
# How _wide_ the columns are, in terminal characters. In this case we have
|
||||
# four columns, each of which are 35 characters wide.
|
||||
# columns: [50, ]
|
||||
# How _high_ the rows are, in terminal lines. In this case we have four rows
|
||||
# that support ten line of text and one of four.
|
||||
# rows: [50]
|
||||
refreshInterval: 1
|
||||
openFileUtil: "open"
|
||||
mods:
|
||||
docker:
|
||||
type: docker
|
||||
title: "💻"
|
||||
enabled: true
|
||||
position:
|
||||
top: 0
|
||||
left: 0
|
||||
height: 3
|
||||
width: 3
|
||||
refreshInterval: 1
|
||||
labelColor: lightblue
|
||||
|
||||
24
modules/docker/settings.go
Normal file
24
modules/docker/settings.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/olebedev/config"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
)
|
||||
|
||||
const defaultTitle = "docker"
|
||||
|
||||
// Settings defines the configuration options for this module
|
||||
type Settings struct {
|
||||
common *cfg.Common
|
||||
labelColor string
|
||||
}
|
||||
|
||||
// NewSettingsFromYAML creates and returns an instance of Settings with configuration options populated
|
||||
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
|
||||
settings := Settings{
|
||||
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig),
|
||||
labelColor: ymlConfig.UString("labelColor", "white"),
|
||||
}
|
||||
|
||||
return &settings
|
||||
}
|
||||
29
modules/docker/utils.go
Normal file
29
modules/docker/utils.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func padSlice(padLeft bool, slice interface{}, getter func(i int) string, setter func(i int, newVal string)) {
|
||||
rv := reflect.ValueOf(slice)
|
||||
length := rv.Len()
|
||||
maxLen := 0
|
||||
for i := 0; i < length; i++ {
|
||||
val := getter(i)
|
||||
maxLen = int(math.Max(float64(len(val)), float64(maxLen)))
|
||||
}
|
||||
|
||||
sign := "-"
|
||||
if padLeft {
|
||||
sign = ""
|
||||
}
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
val := getter(i)
|
||||
val = fmt.Sprintf("%"+sign+strconv.Itoa(maxLen)+"s", val)
|
||||
setter(i, val)
|
||||
}
|
||||
}
|
||||
64
modules/docker/widget.go
Normal file
64
modules/docker/widget.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/view"
|
||||
)
|
||||
|
||||
type Widget struct {
|
||||
view.TextWidget
|
||||
cli *client.Client
|
||||
settings *Settings
|
||||
displayBuffer string
|
||||
}
|
||||
|
||||
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: view.NewTextWidget(app, settings.common, false),
|
||||
settings: settings,
|
||||
}
|
||||
|
||||
widget.View.SetScrollable(true)
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
widget.displayBuffer = errors.Wrap(err, "could not create client").Error()
|
||||
} else {
|
||||
widget.cli = cli
|
||||
}
|
||||
|
||||
widget.refreshDisplayBuffer()
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) Refresh() {
|
||||
widget.refreshDisplayBuffer()
|
||||
widget.Redraw(widget.display)
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) display() (string, string, bool) {
|
||||
return widget.CommonSettings().Title, widget.displayBuffer, true
|
||||
}
|
||||
|
||||
func (widget *Widget) refreshDisplayBuffer() {
|
||||
if widget.cli == nil {
|
||||
return
|
||||
}
|
||||
|
||||
widget.displayBuffer = ""
|
||||
|
||||
widget.displayBuffer += "[" + widget.settings.labelColor + "::bul]system\n"
|
||||
widget.displayBuffer += widget.getSystemInfo()
|
||||
|
||||
widget.displayBuffer += "\n"
|
||||
|
||||
widget.displayBuffer += "[" + widget.settings.labelColor + "::bul]containers\n"
|
||||
widget.displayBuffer += widget.getContainerStates()
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/olebedev/config"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
)
|
||||
|
||||
const defaultTitle = "GitHub"
|
||||
@@ -42,26 +40,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
|
||||
uploadURL: ymlConfig.UString("uploadURL", os.Getenv("WTF_GITHUB_UPLOAD_URL")),
|
||||
username: ymlConfig.UString("username"),
|
||||
}
|
||||
settings.repositories = parseRepositories(ymlConfig)
|
||||
settings.repositories = cfg.ParseAsMapOrList(ymlConfig, "repositories")
|
||||
settings.customQueries = parseCustomQueries(ymlConfig)
|
||||
|
||||
return &settings
|
||||
}
|
||||
|
||||
func parseRepositories(ymlConfig *config.Config) []string {
|
||||
|
||||
result := []string{}
|
||||
repositories, err := ymlConfig.Map("repositories")
|
||||
if err == nil {
|
||||
for key, value := range repositories {
|
||||
result = append(result, fmt.Sprintf("%s/%s", value, key))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
result = utils.ToStrs(ymlConfig.UList("repositories"))
|
||||
return result
|
||||
}
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func parseCustomQueries(ymlConfig *config.Config) []customQuery {
|
||||
result := []customQuery{}
|
||||
|
||||
@@ -73,5 +73,5 @@ func (widget *Widget) displayStats(project *GitlabProject) string {
|
||||
}
|
||||
|
||||
func (widget *Widget) title(project *GitlabProject) string {
|
||||
return fmt.Sprintf("[green]%s [white]", project.Path)
|
||||
return fmt.Sprintf("[green]%s [white]", project.path)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,17 @@ import (
|
||||
)
|
||||
|
||||
type GitlabProject struct {
|
||||
gitlab *glb.Client
|
||||
Path string
|
||||
client *glb.Client
|
||||
path string
|
||||
|
||||
MergeRequests []*glb.MergeRequest
|
||||
RemoteProject *glb.Project
|
||||
}
|
||||
|
||||
func NewGitlabProject(name string, namespace string, gitlab *glb.Client) *GitlabProject {
|
||||
path := namespace + "/" + name
|
||||
func NewGitlabProject(projectPath string, client *glb.Client) *GitlabProject {
|
||||
project := GitlabProject{
|
||||
gitlab: gitlab,
|
||||
Path: path,
|
||||
client: client,
|
||||
path: projectPath,
|
||||
}
|
||||
|
||||
return &project
|
||||
@@ -73,7 +72,7 @@ func (project *GitlabProject) myApprovalRequests(username string) []*glb.MergeRe
|
||||
mrs := []*glb.MergeRequest{}
|
||||
|
||||
for _, mr := range project.MergeRequests {
|
||||
approvers, _, err := project.gitlab.MergeRequests.GetMergeRequestApprovals(project.Path, mr.IID)
|
||||
approvers, _, err := project.client.MergeRequests.GetMergeRequestApprovals(project.path, mr.IID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -93,7 +92,7 @@ func (project *GitlabProject) loadMergeRequests() ([]*glb.MergeRequest, error) {
|
||||
State: &state,
|
||||
}
|
||||
|
||||
mrs, _, err := project.gitlab.MergeRequests.ListProjectMergeRequests(project.Path, &opts)
|
||||
mrs, _, err := project.client.MergeRequests.ListProjectMergeRequests(project.path, &opts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,7 +102,7 @@ func (project *GitlabProject) loadMergeRequests() ([]*glb.MergeRequest, error) {
|
||||
}
|
||||
|
||||
func (project *GitlabProject) loadRemoteProject() (*glb.Project, error) {
|
||||
projectsitory, _, err := project.gitlab.Projects.GetProject(project.Path, nil)
|
||||
projectsitory, _, err := project.client.Projects.GetProject(project.path, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -9,25 +9,27 @@ import (
|
||||
|
||||
const defaultTitle = "GitLab"
|
||||
|
||||
// Settings defines the configuration properties for this module
|
||||
type Settings struct {
|
||||
common *cfg.Common
|
||||
|
||||
apiKey string `help:"A GitLab personal access token. Requires at least api access."`
|
||||
domain string `help:"Your GitLab corporate domain."`
|
||||
projects map[string]interface{} `help:"A list of key/value pairs each describing a GitLab project to fetch data for." values:"Key: The name of the project. Value: The namespace of the project."`
|
||||
username string `help:"Your GitLab username. Used to figure out which requests require your approval"`
|
||||
apiKey string `help:"A GitLab personal access token. Requires at least api access."`
|
||||
domain string `help:"Your GitLab corporate domain."`
|
||||
projects []string `help:"A list of key/value pairs each describing a GitLab project to fetch data for." values:"Key: The name of the project. Value: The namespace of the project."`
|
||||
username string `help:"Your GitLab username. Used to figure out which requests require your approval"`
|
||||
}
|
||||
|
||||
// NewSettingsFromYAML creates a new settings instance from a YAML config block
|
||||
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
|
||||
|
||||
settings := Settings{
|
||||
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig),
|
||||
|
||||
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_GITLAB_TOKEN"))),
|
||||
domain: ymlConfig.UString("domain"),
|
||||
projects: ymlConfig.UMap("projects"),
|
||||
username: ymlConfig.UString("username"),
|
||||
}
|
||||
|
||||
settings.projects = cfg.ParseAsMapOrList(ymlConfig, "projects")
|
||||
|
||||
return &settings
|
||||
}
|
||||
|
||||
@@ -61,11 +61,11 @@ func (widget *Widget) HelpText() string {
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) buildProjectCollection(projectData map[string]interface{}) []*GitlabProject {
|
||||
func (widget *Widget) buildProjectCollection(projectData []string) []*GitlabProject {
|
||||
gitlabProjects := []*GitlabProject{}
|
||||
|
||||
for name, namespace := range projectData {
|
||||
project := NewGitlabProject(name, namespace.(string), widget.gitlab)
|
||||
for _, projectPath := range projectData {
|
||||
project := NewGitlabProject(projectPath, widget.gitlab)
|
||||
gitlabProjects = append(gitlabProjects, project)
|
||||
}
|
||||
|
||||
|
||||
74
modules/newrelic/display.go
Normal file
74
modules/newrelic/display.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package newrelic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
nr "github.com/yfronto/newrelic"
|
||||
)
|
||||
|
||||
func (widget *Widget) content() (string, string, bool) {
|
||||
client := widget.currentData()
|
||||
if client == nil {
|
||||
return widget.CommonSettings().Title, " NewRelic data unavailable ", false
|
||||
}
|
||||
app, appErr := client.Application()
|
||||
deploys, depErr := client.Deployments()
|
||||
|
||||
appName := "error"
|
||||
if appErr == nil {
|
||||
appName = app.Name
|
||||
}
|
||||
|
||||
var content string
|
||||
title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings().Title, appName)
|
||||
wrap := false
|
||||
if depErr != nil {
|
||||
wrap = true
|
||||
content = depErr.Error()
|
||||
} else {
|
||||
content = widget.contentFrom(deploys)
|
||||
}
|
||||
|
||||
return title, content, wrap
|
||||
}
|
||||
|
||||
func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string {
|
||||
str := fmt.Sprintf(
|
||||
" %s\n",
|
||||
"[red]Latest Deploys[white]",
|
||||
)
|
||||
|
||||
revisions := []string{}
|
||||
|
||||
for _, deploy := range deploys {
|
||||
if (deploy.Revision != "") && utils.DoesNotInclude(revisions, deploy.Revision) {
|
||||
lineColor := "white"
|
||||
if wtf.IsToday(deploy.Timestamp) {
|
||||
lineColor = "lightblue"
|
||||
}
|
||||
|
||||
revLen := 8
|
||||
if revLen > len(deploy.Revision) {
|
||||
revLen = len(deploy.Revision)
|
||||
}
|
||||
|
||||
str += fmt.Sprintf(
|
||||
" [green]%s[%s] %s %-.16s[white]\n",
|
||||
deploy.Revision[0:revLen],
|
||||
lineColor,
|
||||
deploy.Timestamp.Format("Jan 02 15:04 MST"),
|
||||
utils.NameFromEmail(deploy.User),
|
||||
)
|
||||
|
||||
revisions = append(revisions, deploy.Revision)
|
||||
|
||||
if len(revisions) == widget.settings.deployCount {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
9
modules/newrelic/keyboard.go
Normal file
9
modules/newrelic/keyboard.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package newrelic
|
||||
|
||||
import "github.com/gdamore/tcell"
|
||||
|
||||
func (widget *Widget) initializeKeyboardControls() {
|
||||
widget.SetKeyboardChar("/", widget.ShowHelp, "Show/hide this help window")
|
||||
widget.SetKeyboardKey(tcell.KeyLeft, widget.PrevSource, "Select previous application")
|
||||
widget.SetKeyboardKey(tcell.KeyRight, widget.NextSource, "Select next application")
|
||||
}
|
||||
@@ -12,9 +12,9 @@ const defaultTitle = "NewRelic"
|
||||
type Settings struct {
|
||||
common *cfg.Common
|
||||
|
||||
apiKey string `help:"Your New Relic API token."`
|
||||
applicationID int `help:"The integer ID of the New Relic application you wish to report on."`
|
||||
deployCount int `help:"The number of past deploys to display on screen." optional:"true"`
|
||||
apiKey string `help:"Your New Relic API token."`
|
||||
deployCount int `help:"The number of past deploys to display on screen." optional:"true"`
|
||||
applicationIDs []interface{} `help:"The integer ID of the New Relic application you wish to report on."`
|
||||
}
|
||||
|
||||
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
|
||||
@@ -22,9 +22,9 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
|
||||
settings := Settings{
|
||||
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig),
|
||||
|
||||
apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_NEW_RELIC_API_KEY"))),
|
||||
applicationID: ymlConfig.UInt("applicationID"),
|
||||
deployCount: ymlConfig.UInt("deployCount", 5),
|
||||
apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_NEW_RELIC_API_KEY")),
|
||||
deployCount: ymlConfig.UInt("deployCount", 5),
|
||||
applicationIDs: ymlConfig.UList("applicationIDs"),
|
||||
}
|
||||
|
||||
return &settings
|
||||
|
||||
@@ -1,29 +1,46 @@
|
||||
package newrelic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
"github.com/wtfutil/wtf/view"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type Widget struct {
|
||||
view.KeyboardWidget
|
||||
view.MultiSourceWidget
|
||||
view.TextWidget
|
||||
|
||||
client *Client
|
||||
Clients []*Client
|
||||
|
||||
settings *Settings
|
||||
}
|
||||
|
||||
func NewWidget(app *tview.Application, settings *Settings) *Widget {
|
||||
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: view.NewTextWidget(app, settings.common, false),
|
||||
KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
|
||||
MultiSourceWidget: view.NewMultiSourceWidget(settings.common, "applicationID", "applicationIDs"),
|
||||
TextWidget: view.NewTextWidget(app, settings.common, true),
|
||||
|
||||
settings: settings,
|
||||
}
|
||||
|
||||
widget.client = NewClient(widget.settings.apiKey, widget.settings.applicationID)
|
||||
widget.initializeKeyboardControls()
|
||||
widget.View.SetInputCapture(widget.InputCapture)
|
||||
|
||||
for _, id := range utils.ToInts(widget.settings.applicationIDs) {
|
||||
widget.Clients = append(widget.Clients, NewClient(widget.settings.apiKey, id))
|
||||
}
|
||||
|
||||
sort.Slice(widget.Clients, func(i, j int) bool {
|
||||
return widget.Clients[i].applicationId < widget.Clients[j].applicationId
|
||||
})
|
||||
|
||||
widget.SetDisplayFunction(widget.Refresh)
|
||||
|
||||
widget.KeyboardWidget.SetView(widget.View)
|
||||
|
||||
return &widget
|
||||
}
|
||||
@@ -36,57 +53,20 @@ func (widget *Widget) Refresh() {
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) content() (string, string, bool) {
|
||||
app, appErr := widget.client.Application()
|
||||
deploys, depErr := widget.client.Deployments()
|
||||
|
||||
appName := "error"
|
||||
if appErr == nil {
|
||||
appName = app.Name
|
||||
}
|
||||
|
||||
var content string
|
||||
title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings().Title, appName)
|
||||
wrap := false
|
||||
if depErr != nil {
|
||||
wrap = true
|
||||
content = depErr.Error()
|
||||
} else {
|
||||
content += fmt.Sprintf(
|
||||
" %s\n",
|
||||
"[red]Latest Deploys[white]",
|
||||
)
|
||||
|
||||
revisions := []string{}
|
||||
|
||||
for _, deploy := range deploys {
|
||||
if (deploy.Revision != "") && utils.DoesNotInclude(revisions, deploy.Revision) {
|
||||
lineColor := "white"
|
||||
if wtf.IsToday(deploy.Timestamp) {
|
||||
lineColor = "lightblue"
|
||||
}
|
||||
|
||||
revLen := 8
|
||||
if revLen > len(deploy.Revision) {
|
||||
revLen = len(deploy.Revision)
|
||||
}
|
||||
|
||||
content += fmt.Sprintf(
|
||||
" [green]%s[%s] %s %-.16s[white]\n",
|
||||
deploy.Revision[0:revLen],
|
||||
lineColor,
|
||||
deploy.Timestamp.Format("Jan 02 15:04 MST"),
|
||||
utils.NameFromEmail(deploy.User),
|
||||
)
|
||||
|
||||
revisions = append(revisions, deploy.Revision)
|
||||
|
||||
if len(revisions) == widget.settings.deployCount {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return title, content, wrap
|
||||
func (widget *Widget) HelpText() string {
|
||||
return widget.KeyboardWidget.HelpText()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) currentData() *Client {
|
||||
if len(widget.Clients) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if widget.Idx < 0 || widget.Idx >= len(widget.Clients) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return widget.Clients[widget.Idx]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user