added backend calls skeleton

This commit is contained in:
sqshq 2019-05-23 22:58:46 -04:00
parent 6bc8b580cb
commit 4ec36459d8
11 changed files with 132 additions and 70 deletions

View File

@ -1,8 +1,35 @@
package client package client
import "github.com/sqshq/sampler/storage" import (
"github.com/sqshq/sampler/metadata"
"net/http"
)
// TODO const (
func loadLicense(key string) *storage.License { backendUrl = "http://localhost:8080/api/v1"
return nil registrationPath = "/registration"
reportInstallationPath = "/report/installation"
reportCrashPath = "repost/crash"
)
type BackendClient struct {
client http.Client
}
func NewBackendClient() *BackendClient {
return &BackendClient{
client: http.Client{},
}
}
func (c *BackendClient) ReportInstallation(statistics *metadata.Statistics) {
// TODO
}
func (c *BackendClient) ReportCrash() {
// TODO
}
func (c *BackendClient) Register(key string) {
// TODO
} }

View File

@ -41,8 +41,9 @@ const (
statusbarHeight = 1 statusbarHeight = 1
) )
func NewLayout(width, height int, statusline *component.StatusBar, menu *component.Menu, intro *component.Intro) *Layout { func NewLayout(statusline *component.StatusBar, menu *component.Menu, intro *component.Intro) *Layout {
width, height := ui.TerminalDimensions()
block := *ui.NewBlock() block := *ui.NewBlock()
block.SetRect(0, 0, width, height) block.SetRect(0, 0, width, height)
intro.SetRect(0, 0, width, height) intro.SetRect(0, 0, width, height)

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
ui "github.com/gizak/termui/v3" ui "github.com/gizak/termui/v3"
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/storage" "github.com/sqshq/sampler/metadata"
"image" "image"
) )
@ -18,7 +18,7 @@ type StatusBar struct {
text string text string
} }
func NewStatusLine(configFileName string, palette console.Palette, license *storage.License) *StatusBar { func NewStatusLine(configFileName string, palette console.Palette, license *metadata.License) *StatusBar {
block := *ui.NewBlock() block := *ui.NewBlock()
block.Border = false block.Border = false

View File

@ -21,20 +21,34 @@ type Config struct {
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"` AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
} }
func LoadConfig() (Config, Options) { func LoadConfig() (*Config, Options) {
var opt Options var opt Options
_, err := flags.Parse(&opt) _, err := flags.Parse(&opt)
if err != nil { if err != nil {
panic(err)
}
if opt.Version == true {
println(console.AppVersion)
os.Exit(0) os.Exit(0)
} }
if opt.ConfigFile == nil && opt.License == nil {
println("Please specify config file using --config flag. Example: sampler --config example.yml")
os.Exit(0)
}
if opt.License != nil {
return nil, opt
}
cfg := readFile(opt.ConfigFile) cfg := readFile(opt.ConfigFile)
cfg.validate() cfg.validate()
cfg.setDefaults() cfg.setDefaults()
return *cfg, opt return cfg, opt
} }
func Update(settings []ComponentSettings, options Options) { func Update(settings []ComponentSettings, options Options) {
@ -91,11 +105,11 @@ func (c *Config) findComponent(componentType ComponentType, componentTitle strin
"Failed to find component type %v with title %v", componentType, componentTitle)) "Failed to find component type %v with title %v", componentType, componentTitle))
} }
func readFile(location string) *Config { func readFile(location *string) *Config {
yamlFile, err := ioutil.ReadFile(location) yamlFile, err := ioutil.ReadFile(*location)
if err != nil { if err != nil {
log.Fatalf("Failed to read config file: %s", location) log.Fatalf("Failed to read config file: %s", *location)
} }
cfg := new(Config) cfg := new(Config)
@ -108,13 +122,12 @@ func readFile(location string) *Config {
return cfg return cfg
} }
func saveFile(config *Config, fileName string) { func saveFile(config *Config, fileName *string) {
file, err := yaml.Marshal(config) file, err := yaml.Marshal(config)
if err != nil { if err != nil {
log.Fatalf("Failed to marshal config file: %v", err) log.Fatalf("Failed to marshal config file: %v", err)
} }
err = ioutil.WriteFile(*fileName, file, os.ModePerm)
err = ioutil.WriteFile(fileName, file, os.ModePerm)
if err != nil { if err != nil {
log.Fatalf("Failed to save config file: %v", err) log.Fatalf("Failed to save config file: %v", err)
} }

View File

@ -1,7 +1,8 @@
package config package config
type Options struct { type Options struct {
ConfigFile string `short:"c" long:"config" required:"true" description:"path to YAML config file"` ConfigFile *string `short:"c" long:"config" required:"false" description:"set path to YAML config file"`
Variables []string `short:"v" long:"variable" required:"false" description:"specify name=value variable to use in script placeholder as $name. This flag takes precedence over the same name variables, specified in config yml" long-description:"one or more variables can be specified as flags, in order to replace repeated patterns in the scripts, which can be replaced with {$variable-name} placeholder" ` License *string `short:"l" long:"license" required:"false" description:"provide license key. visit www.sampler.dev for details"`
License []string `short:"l" long:"license" required:"false" description:"provide license key. visit www.sampler.dev for details"` Environment []string `short:"e" long:"env" required:"false" description:"specify name=value variable to use in script placeholder as $name. This flag takes precedence over the same name variables, specified in config yml"`
Version bool `short:"v" long:"version" required:"false" description:"print version"`
} }

View File

@ -23,7 +23,7 @@ func NewSampler(consumer *Consumer, items []*Item, triggers []*Trigger, options
items, items,
triggers, triggers,
make(chan *Sample), make(chan *Sample),
mergeVariables(fileVariables, options.Variables), mergeVariables(fileVariables, options.Environment),
} }
go func() { go func() {

View File

@ -120,7 +120,7 @@ func (t *Trigger) runScript(script, label string, data Values) ([]byte, error) {
cmd := exec.Command("sh", "-c", script) cmd := exec.Command("sh", "-c", script)
cmd.Env = os.Environ() cmd.Env = os.Environ()
for _, variable := range t.options.Variables { for _, variable := range t.options.Environment {
cmd.Env = append(cmd.Env, variable) cmd.Env = append(cmd.Env, variable)
} }

85
main.go
View File

@ -3,6 +3,7 @@ package main
import ( import (
ui "github.com/gizak/termui/v3" ui "github.com/gizak/termui/v3"
"github.com/sqshq/sampler/asset" "github.com/sqshq/sampler/asset"
"github.com/sqshq/sampler/client"
"github.com/sqshq/sampler/component" "github.com/sqshq/sampler/component"
"github.com/sqshq/sampler/component/asciibox" "github.com/sqshq/sampler/component/asciibox"
"github.com/sqshq/sampler/component/barchart" "github.com/sqshq/sampler/component/barchart"
@ -15,7 +16,7 @@ import (
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data" "github.com/sqshq/sampler/data"
"github.com/sqshq/sampler/event" "github.com/sqshq/sampler/event"
"github.com/sqshq/sampler/storage" "github.com/sqshq/sampler/metadata"
"time" "time"
) )
@ -45,54 +46,58 @@ func main() {
player := asset.NewAudioPlayer() player := asset.NewAudioPlayer()
defer player.Close() defer player.Close()
license := metadata.GetLicense()
statistics := metadata.PersistStatistics(cfg)
if opt.License != nil {
// validate license
// save to storage on success
// exit with info
return
}
palette := console.GetPalette(*cfg.Theme) palette := console.GetPalette(*cfg.Theme)
width, height := ui.TerminalDimensions() lout := layout.NewLayout(component.NewStatusLine(*opt.ConfigFile, palette, license), component.NewMenu(palette), component.NewIntro(palette))
bc := client.NewBackendClient()
license := storage.GetLicense()
_ = storage.UpdateStatistics(cfg, width, height)
lout := layout.NewLayout(width, height, component.NewStatusLine(opt.ConfigFile, palette, license), component.NewMenu(palette), component.NewIntro(palette))
starter := &Starter{lout, player, opt, cfg}
if license == nil { if license == nil {
lout.RunIntro() lout.RunIntro()
storage.InitLicense() metadata.InitLicense()
bc.ReportInstallation(statistics)
} else if !license.Purchased /* && random */ { } else if !license.Purchased /* && random */ {
// TODO lout.showNagWindow() with timeout and OK button // TODO lout.showNagWindow() with timeout and OK button
// TODO verify license
// TODO send stats
} }
for _, c := range cfg.RunCharts { starter := &Starter{lout, player, opt, *cfg}
cpt := runchart.NewRunChart(c, palette) startComponents(starter, cfg, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
}
for _, c := range cfg.SparkLines {
cpt := sparkline.NewSparkLine(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.BarCharts {
cpt := barchart.NewBarChart(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
}
for _, c := range cfg.Gauges {
cpt := gauge.NewGauge(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Cur, c.Min, c.Max}, c.Triggers)
}
for _, c := range cfg.AsciiBoxes {
cpt := asciibox.NewAsciiBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.TextBoxes {
cpt := textbox.NewTextBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
handler := event.NewHandler(lout, opt) handler := event.NewHandler(lout, opt)
handler.HandleEvents() handler.HandleEvents()
} }
func startComponents(starter *Starter, cfg *config.Config, palette console.Palette) {
for _, c := range cfg.RunCharts {
cpt := runchart.NewRunChart(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
}
for _, c := range cfg.SparkLines {
cpt := sparkline.NewSparkLine(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.BarCharts {
cpt := barchart.NewBarChart(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
}
for _, c := range cfg.Gauges {
cpt := gauge.NewGauge(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Cur, c.Min, c.Max}, c.Triggers)
}
for _, c := range cfg.AsciiBoxes {
cpt := asciibox.NewAsciiBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.TextBoxes {
cpt := textbox.NewTextBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
}

View File

@ -1,4 +1,4 @@
package storage package metadata
import ( import (
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"

View File

@ -1,6 +1,7 @@
package storage package metadata
import ( import (
ui "github.com/gizak/termui/v3"
"github.com/sqshq/sampler/config" "github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -19,27 +20,34 @@ type Statistics struct {
const statisticsFileName = "statistics.yml" const statisticsFileName = "statistics.yml"
func UpdateStatistics(config config.Config, width int, height int) *Statistics { func PersistStatistics(config *config.Config) *Statistics {
statistics := new(Statistics) statistics := new(Statistics)
w, h := ui.TerminalDimensions()
if fileExists(statisticsFileName) { if fileExists(statisticsFileName) {
file := readStorageFile(getPlatformStoragePath(statisticsFileName)) file := readStorageFile(getPlatformStoragePath(statisticsFileName))
err := yaml.Unmarshal(file, statistics) err := yaml.Unmarshal(file, statistics)
if err != nil { if err != nil {
log.Fatalf("Failed to read statistics file: %v", err) log.Fatalf("Failed to read statistics file: %v", err)
} }
statistics.ComponentsCount = countComponentsPerType(config)
statistics.WindowWidth = width if config != nil {
statistics.WindowWidth = height statistics.ComponentsCount = countComponentsPerType(config)
}
statistics.WindowWidth = w
statistics.WindowWidth = h
statistics.LaunchCount += 1 statistics.LaunchCount += 1
} else { } else {
statistics = &Statistics{ statistics = &Statistics{
Version: console.AppVersion, Version: console.AppVersion,
OS: runtime.GOOS, OS: runtime.GOOS,
LaunchCount: 1, LaunchCount: 1,
WindowWidth: width, WindowWidth: w,
WindowHeight: height, WindowHeight: h,
ComponentsCount: countComponentsPerType(config), ComponentsCount: countComponentsPerType(config),
} }
} }
@ -54,13 +62,20 @@ func UpdateStatistics(config config.Config, width int, height int) *Statistics {
return statistics return statistics
} }
func countComponentsPerType(config config.Config) map[string]int { func countComponentsPerType(config *config.Config) map[string]int {
m := make(map[string]int) m := make(map[string]int)
if config == nil {
return m
}
m["runcharts"] = len(config.RunCharts) m["runcharts"] = len(config.RunCharts)
m["sparkLines"] = len(config.SparkLines) m["sparkLines"] = len(config.SparkLines)
m["barcharts"] = len(config.BarCharts) m["barcharts"] = len(config.BarCharts)
m["gauges"] = len(config.Gauges) m["gauges"] = len(config.Gauges)
m["asciiboxes"] = len(config.AsciiBoxes) m["asciiboxes"] = len(config.AsciiBoxes)
m["textboxes"] = len(config.TextBoxes) m["textboxes"] = len(config.TextBoxes)
return m return m
} }

View File

@ -1,4 +1,4 @@
package storage package metadata
import ( import (
"io/ioutil" "io/ioutil"