Resolves merge conflicts
This commit is contained in:
commit
daf5916fde
44
LICENSE
44
LICENSE
|
@ -1,29 +1,25 @@
|
|||
The MIT License (MIT)
|
||||
The MIT License (Festival variant)
|
||||
|
||||
Copyright (c) 2020 Sean E. Russell <ser@ser1.net> 87651D71
|
||||
Permission is hereby granted, free of charge, to use and distribute this
|
||||
software and its documentation without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of this work, and to permit persons to whom
|
||||
this work is furnished to do so, subject to the following conditions:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. The codemust retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
2. Any modifications must be clearly marked as such.
|
||||
3. Original authors' names are not deleted.
|
||||
4. The authors' names are not used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS NOR THE
|
||||
CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
https://fedoraproject.org/wiki/Licensing:MIT?rd=Licensing/MIT#Festival_variant
|
||||
|
|
|
@ -73,6 +73,10 @@ Move `gotop` to somewhere in your `$PATH`.
|
|||
|
||||
If Go is not installed or is the wrong version, and you don't have root access or don't want to upgrade Go, a script is provided to download Go and the gotop sources, compile gotop, and then clean up. See `scripts/install_without_root.sh`.
|
||||
|
||||
#### go generate
|
||||
|
||||
Apple SMC tags are embedded in a text file that is compiled into the executable; the same happens with the language translations. When the file `devices/data/sm.tsv` or any translations in `translations/dicts/` change, `go generate` should be re-run.
|
||||
|
||||
## Usage
|
||||
|
||||
Run with `-h` to get an extensive list of command line arguments. Many of these can be configured by creating a configuration file; see the next section for more information. Key bindings can be viewed while gotop is running by pressing the `?` key, or they can be printed out by using the `--list keys` command.
|
||||
|
@ -114,6 +118,7 @@ For more information on other topics, see:
|
|||
- [goreleaser/nfpm](https://github.com/goreleaser/nfpm)
|
||||
- [distatus/battery](https://github.com/distatus/battery)
|
||||
- [VictoriaMetrics/metrics](https://github.com/VictoriaMetrics/metrics) Check this out! The API is clean, elegant, introduces many fewer indirect dependencies than the Prometheus client, and adds 50% less size to binaries.
|
||||
- [lingo-toml](https://github.com/jdkeke142/lingo-toml) provides the translation support library.
|
||||
|
||||
## History
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -18,7 +19,9 @@ import (
|
|||
//_ "net/http/pprof"
|
||||
|
||||
"github.com/VictoriaMetrics/metrics"
|
||||
jj "github.com/cloudfoundry-attic/jibber_jabber"
|
||||
ui "github.com/gizak/termui/v3"
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
"github.com/shibukawa/configdir"
|
||||
"github.com/xxxserxxx/opflag"
|
||||
|
||||
|
@ -27,7 +30,7 @@ import (
|
|||
"github.com/xxxserxxx/gotop/v4/devices"
|
||||
"github.com/xxxserxxx/gotop/v4/layout"
|
||||
"github.com/xxxserxxx/gotop/v4/logging"
|
||||
"github.com/xxxserxxx/gotop/v4/widgets"
|
||||
"github.com/xxxserxxx/gotop/v4/translations"
|
||||
w "github.com/xxxserxxx/gotop/v4/widgets"
|
||||
)
|
||||
|
||||
|
@ -50,6 +53,7 @@ var (
|
|||
bar *w.StatusBar
|
||||
statusbar bool
|
||||
stderrLogger = log.New(os.Stderr, "", 0)
|
||||
tr lingo.Translations
|
||||
)
|
||||
|
||||
func parseArgs() error {
|
||||
|
@ -58,33 +62,27 @@ func parseArgs() error {
|
|||
for i, p := range cds {
|
||||
cpaths[i] = p.Path
|
||||
}
|
||||
help := opflag.BoolP("help", "h", false, "Show this screen.")
|
||||
color := opflag.StringP("color", "c", conf.Colorscheme.Name, "Set a colorscheme.")
|
||||
opflag.IntVarP(&conf.GraphHorizontalScale, "graphscale", "S", conf.GraphHorizontalScale, "Graph scale factor, >0")
|
||||
version := opflag.BoolP("version", "v", false, "Print version and exit.")
|
||||
versioN := opflag.BoolP("", "V", false, "Print version and exit.")
|
||||
opflag.BoolVarP(&conf.PercpuLoad, "percpu", "p", conf.PercpuLoad, "Show each CPU in the CPU widget.")
|
||||
opflag.BoolVarP(&conf.AverageLoad, "averagecpu", "a", conf.AverageLoad, "Show average CPU in the CPU widget.")
|
||||
fahrenheit := opflag.BoolP("fahrenheit", "f", conf.TempScale == 'F', "Show temperatures in fahrenheit.Show temperatures in fahrenheit.")
|
||||
opflag.BoolVarP(&conf.Statusbar, "statusbar", "s", conf.Statusbar, "Show a statusbar with the time.")
|
||||
opflag.DurationVarP(&conf.UpdateInterval, "rate", "r", conf.UpdateInterval, "Refresh frequency. Most time units accepted. `1m` = refresh every minute. `100ms` = refresh every 100ms.")
|
||||
opflag.StringVarP(&conf.Layout, "layout", "l", conf.Layout, `Name of layout spec file for the UI. Use "-" to pipe.`)
|
||||
opflag.StringVarP(&conf.NetInterface, "interface", "i", "all", "Select network interface. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using `!`")
|
||||
opflag.StringVarP(&conf.ExportPort, "export", "x", conf.ExportPort, "Enable metrics for export on the specified port.")
|
||||
opflag.BoolVarP(&conf.Mbps, "mbps", "", conf.Mbps, "Show network rate as mbps.")
|
||||
opflag.BoolVar(&conf.Test, "test", conf.Test, "Runs tests and exits with success/failure code.")
|
||||
opflag.StringP("", "C", "", "Config file to use instead of default (MUST BE FIRST ARGUMENT)")
|
||||
list := opflag.String("list", "", `List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: Prints out device names for filterable widgets
|
||||
layouts: Lists build-in layouts
|
||||
colorschemes: Lists built-in colorschemes
|
||||
paths: List out configuration file search paths
|
||||
widgets: Widgets that can be used in a layout
|
||||
keys: Show the keyboard bindings.`)
|
||||
wc := opflag.Bool("write-config", false, "Write out a default config file.")
|
||||
help := opflag.BoolP("help", "h", false, tr.Value("args.help"))
|
||||
color := opflag.StringP("color", "c", conf.Colorscheme.Name, tr.Value("args.color"))
|
||||
opflag.IntVarP(&conf.GraphHorizontalScale, "graphscale", "S", conf.GraphHorizontalScale, tr.Value("args.scale"))
|
||||
version := opflag.BoolP("version", "v", false, tr.Value("args.version"))
|
||||
versioN := opflag.BoolP("", "V", false, tr.Value("args.version"))
|
||||
opflag.BoolVarP(&conf.PercpuLoad, "percpu", "p", conf.PercpuLoad, tr.Value("args.percpu"))
|
||||
opflag.BoolVarP(&conf.AverageLoad, "averagecpu", "a", conf.AverageLoad, tr.Value("args.cpuavg"))
|
||||
fahrenheit := opflag.BoolP("fahrenheit", "f", conf.TempScale == 'F', tr.Value("args.temp"))
|
||||
opflag.BoolVarP(&conf.Statusbar, "statusbar", "s", conf.Statusbar, tr.Value("args.statusbar"))
|
||||
opflag.DurationVarP(&conf.UpdateInterval, "rate", "r", conf.UpdateInterval, tr.Value("args.rate"))
|
||||
opflag.StringVarP(&conf.Layout, "layout", "l", conf.Layout, tr.Value("args.layout"))
|
||||
opflag.StringVarP(&conf.NetInterface, "interface", "i", "all", tr.Value("args.net"))
|
||||
opflag.StringVarP(&conf.ExportPort, "export", "x", conf.ExportPort, tr.Value("args.export"))
|
||||
opflag.BoolVarP(&conf.Mbps, "mbps", "", conf.Mbps, tr.Value("args.mbps"))
|
||||
opflag.BoolVar(&conf.Test, "test", conf.Test, tr.Value("args.test"))
|
||||
opflag.StringP("", "C", "", tr.Value("args.conffile"))
|
||||
list := opflag.String("list", "", tr.Value("args.list"))
|
||||
wc := opflag.Bool("write-config", false, tr.Value("args.write"))
|
||||
opflag.SortFlags = false
|
||||
opflag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\nOptions:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, tr.Value("usage", os.Args[0]))
|
||||
opflag.PrintDefaults()
|
||||
}
|
||||
opflag.Parse()
|
||||
|
@ -109,25 +107,26 @@ func parseArgs() error {
|
|||
if *list != "" {
|
||||
switch *list {
|
||||
case "layouts":
|
||||
fmt.Println(_layouts)
|
||||
fmt.Println(tr.Value("help.layouts"))
|
||||
case "colorschemes":
|
||||
fmt.Println(_colorschemes)
|
||||
fmt.Println(tr.Value("help.colorschemes"))
|
||||
case "paths":
|
||||
fmt.Println("Loadable colorschemes & layouts, and the config file, are searched for, in order:")
|
||||
fmt.Println(tr.Value("help.paths"))
|
||||
paths := make([]string, 0)
|
||||
for _, d := range conf.ConfigDir.QueryFolders(configdir.All) {
|
||||
paths = append(paths, d.Path)
|
||||
}
|
||||
fmt.Println(strings.Join(paths, "\n"))
|
||||
fmt.Printf("\nThe log file is in %s\n", filepath.Join(conf.ConfigDir.QueryCacheFolder().Path, logging.LOGFILE))
|
||||
fmt.Println()
|
||||
fmt.Println(tr.Value("help.log", filepath.Join(conf.ConfigDir.QueryCacheFolder().Path, logging.LOGFILE)))
|
||||
case "devices":
|
||||
listDevices()
|
||||
case "keys":
|
||||
fmt.Println(widgets.KEYBINDS)
|
||||
fmt.Println(tr.Value("help.help"))
|
||||
case "widgets":
|
||||
fmt.Println(_widgets)
|
||||
fmt.Println(tr.Value("help.widgets"))
|
||||
default:
|
||||
fmt.Printf("Unknown option \"%s\"; try layouts, colorschemes, keys, paths, or devices\n", *list)
|
||||
fmt.Printf(tr.Value("error.unknownopt", *list))
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
|
@ -135,10 +134,10 @@ func parseArgs() error {
|
|||
if *wc {
|
||||
path, err := conf.Write()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to write configuration file: %s\n", err)
|
||||
fmt.Println(tr.Value("error.writefail", err.Error()))
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Config written to %s\n", path)
|
||||
fmt.Println(tr.Value("help.written", path))
|
||||
os.Exit(0)
|
||||
}
|
||||
return nil
|
||||
|
@ -345,38 +344,55 @@ func main() {
|
|||
ec := run()
|
||||
if ec > 0 {
|
||||
if ec < 2 {
|
||||
fmt.Printf("errors encountered; check the log file %s\n", filepath.Join(conf.ConfigDir.QueryCacheFolder().Path, logging.LOGFILE))
|
||||
logpath := filepath.Join(conf.ConfigDir.QueryCacheFolder().Path, logging.LOGFILE)
|
||||
fmt.Println(tr.Value("error.checklog", logpath))
|
||||
bs, _ := ioutil.ReadFile(logpath)
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
}
|
||||
os.Exit(ec)
|
||||
}
|
||||
|
||||
func run() int {
|
||||
ling, err := lingo.New("en_US", "translations", translations.AssetFile())
|
||||
if err != nil {
|
||||
fmt.Printf("failed to load language files: %s\n", err)
|
||||
return 2
|
||||
}
|
||||
lang, err := jj.DetectIETF()
|
||||
if err != nil {
|
||||
lang = "en_US"
|
||||
}
|
||||
lang = strings.Replace(lang, "-", "_", -1)
|
||||
// Get the locale from the os
|
||||
tr = ling.TranslationsForLocale(lang)
|
||||
colorschemes.SetTr(tr)
|
||||
conf = gotop.NewConfig()
|
||||
conf.Tr = tr
|
||||
// Find the config file; look in (1) local, (2) user, (3) global
|
||||
// Check the last argument first
|
||||
fs := flag.NewFlagSet("config", flag.ContinueOnError)
|
||||
cfg := fs.String("C", "", "Config file")
|
||||
cfg := fs.String("C", "", tr.Value("configfile"))
|
||||
fs.SetOutput(bufio.NewWriter(nil))
|
||||
fs.Parse(os.Args[1:])
|
||||
if *cfg != "" {
|
||||
conf.ConfigFile = *cfg
|
||||
}
|
||||
err := conf.Load()
|
||||
err = conf.Load()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to parse config file: %s\n", err)
|
||||
fmt.Println(tr.Value("error.configparse", err.Error()))
|
||||
return 2
|
||||
}
|
||||
// Override with command line arguments
|
||||
err = parseArgs()
|
||||
if err != nil {
|
||||
fmt.Printf("parsing CLI args: %s\n", err)
|
||||
fmt.Println(tr.Value("error.cliparse", err.Error()))
|
||||
return 2
|
||||
}
|
||||
|
||||
logfile, err := logging.New(conf)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to setup log file: %v\n", err)
|
||||
fmt.Println(tr.Value("logsetup", err.Error()))
|
||||
return 2
|
||||
}
|
||||
defer logfile.Close()
|
||||
|
@ -407,7 +423,7 @@ func run() int {
|
|||
defer ui.Close()
|
||||
|
||||
setDefaultTermuiColors(conf) // done before initializing widgets to allow inheriting colors
|
||||
help = w.NewHelpMenu()
|
||||
help = w.NewHelpMenu(tr)
|
||||
if statusbar {
|
||||
bar = w.NewStatusBar()
|
||||
}
|
||||
|
@ -467,7 +483,7 @@ func getLayout(conf gotop.Config) (io.Reader, error) {
|
|||
for _, d := range conf.ConfigDir.QueryFolders(configdir.Existing) {
|
||||
paths = append(paths, d.Path)
|
||||
}
|
||||
return nil, fmt.Errorf("unable find layout file %s in %s", conf.Layout, strings.Join(paths, ", "))
|
||||
return nil, fmt.Errorf(tr.Value("error.findlayout", conf.Layout, strings.Join(paths, ", ")))
|
||||
}
|
||||
lo, err := folder.ReadFile(conf.Layout)
|
||||
if err != nil {
|
||||
|
@ -492,25 +508,3 @@ func listDevices() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const _layouts = `Built-in layouts:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink`
|
||||
const _colorschemes = `Built-in colorschemes:
|
||||
default
|
||||
default-dark (for white background)
|
||||
solarized
|
||||
solarized16-dark
|
||||
solarized16-light
|
||||
monokai
|
||||
vice`
|
||||
const _widgets = `Widgets that can be used in layouts:
|
||||
cpu - CPU load graph
|
||||
mem - Physical & swap memory use graph
|
||||
temp - Sensor temperatures
|
||||
disk - Physical disk partition use
|
||||
power - A battery bar
|
||||
net - Network load
|
||||
procs - Interactive process list`
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
"github.com/shibukawa/configdir"
|
||||
)
|
||||
|
||||
|
@ -17,6 +18,13 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
var tr lingo.Translations
|
||||
|
||||
// Set the translation library
|
||||
func SetTr(tra lingo.Translations) {
|
||||
tr = tra
|
||||
}
|
||||
|
||||
// FromName loads a Colorscheme by name; confDir is used to search
|
||||
// directories for a scheme matching the name. The search order
|
||||
// is the same as for config files.
|
||||
|
@ -46,15 +54,15 @@ func getCustomColorscheme(confDir configdir.ConfigDir, name string) (Colorscheme
|
|||
for _, d := range confDir.QueryFolders(configdir.Existing) {
|
||||
paths = append(paths, d.Path)
|
||||
}
|
||||
return cs, fmt.Errorf("failed to find colorscheme file %s in %s", fn, strings.Join(paths, ", "))
|
||||
return cs, fmt.Errorf(tr.Value("error.colorschemefile", fn, strings.Join(paths, ", ")))
|
||||
}
|
||||
dat, err := folder.ReadFile(fn)
|
||||
if err != nil {
|
||||
return cs, fmt.Errorf("failed to read colorscheme file %s: %v", filepath.Join(folder.Path, fn), err)
|
||||
return cs, fmt.Errorf(tr.Value("error.colorschemeload", filepath.Join(folder.Path, fn), err.Error()))
|
||||
}
|
||||
err = json.Unmarshal(dat, &cs)
|
||||
if err != nil {
|
||||
return cs, fmt.Errorf("failed to parse colorscheme file: %v", err)
|
||||
return cs, fmt.Errorf(tr.Value("error.colorschemeparse", err.Error()))
|
||||
}
|
||||
return cs, nil
|
||||
}
|
||||
|
|
32
config.go
32
config.go
|
@ -1,5 +1,8 @@
|
|||
package gotop
|
||||
|
||||
//go:generate go-bindata -fs -pkg translations -prefix translations -o translations/dicts.go translations/dicts
|
||||
//go:generate go-bindata -pkg devices -prefix devices/data -o devices/smc.go devices/data
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
|
@ -13,6 +16,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
"github.com/shibukawa/configdir"
|
||||
"github.com/xxxserxxx/gotop/v4/colorschemes"
|
||||
"github.com/xxxserxxx/gotop/v4/widgets"
|
||||
|
@ -40,6 +44,7 @@ type Config struct {
|
|||
Test bool
|
||||
ExtensionVars map[string]string
|
||||
ConfigFile string
|
||||
Tr lingo.Translations
|
||||
}
|
||||
|
||||
func NewConfig() Config {
|
||||
|
@ -97,18 +102,15 @@ func load(in io.Reader, conf *Config) error {
|
|||
}
|
||||
kv := strings.Split(l, "=")
|
||||
if len(kv) != 2 {
|
||||
return fmt.Errorf("bad config file syntax; should be KEY=VALUE, was %s", l)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.configsyntax", l))
|
||||
}
|
||||
key := strings.ToLower(kv[0])
|
||||
ln := strconv.Itoa(lineNo)
|
||||
switch key {
|
||||
default:
|
||||
conf.ExtensionVars[key] = kv[1]
|
||||
case "configdir":
|
||||
log.Printf("configdir is deprecated. Ignored configdir=%s", kv[1])
|
||||
case "logdir":
|
||||
log.Printf("logdir is deprecated. Ignored logdir=%s", kv[1])
|
||||
case "logfile":
|
||||
log.Printf("logfile is deprecated. Ignored logfile=%s", kv[1])
|
||||
case "configdir", "logdir", "logfile":
|
||||
log.Printf(conf.Tr.Value("config.err.deprecation", ln, key, kv[1]))
|
||||
case graphhorizontalscale:
|
||||
iv, err := strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
|
@ -118,31 +120,31 @@ func load(in io.Reader, conf *Config) error {
|
|||
case helpvisible:
|
||||
bv, err := strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("line %d: %v", lineNo, err)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.HelpVisible = bv
|
||||
case colorscheme:
|
||||
cs, err := colorschemes.FromName(conf.ConfigDir, kv[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("line %d: %v", lineNo, err)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.Colorscheme = cs
|
||||
case updateinterval:
|
||||
iv, err := strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.UpdateInterval = time.Duration(iv)
|
||||
case averagecpu:
|
||||
bv, err := strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("line %d: %v", lineNo, err)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.AverageLoad = bv
|
||||
case percpuload:
|
||||
bv, err := strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("line %d: %v", lineNo, err)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.PercpuLoad = bv
|
||||
case tempscale:
|
||||
|
@ -153,12 +155,12 @@ func load(in io.Reader, conf *Config) error {
|
|||
conf.TempScale = 'F'
|
||||
default:
|
||||
conf.TempScale = 'C'
|
||||
return fmt.Errorf("invalid TempScale value %s", kv[1])
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.tempscale", kv[1]))
|
||||
}
|
||||
case statusbar:
|
||||
bv, err := strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("line %d: %v", lineNo, err)
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.Statusbar = bv
|
||||
case netinterface:
|
||||
|
@ -168,7 +170,7 @@ func load(in io.Reader, conf *Config) error {
|
|||
case maxlogsize:
|
||||
iv, err := strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf(conf.Tr.Value("config.err.line", ln, err.Error()))
|
||||
}
|
||||
conf.MaxLogSize = int64(iv)
|
||||
case export:
|
||||
|
|
|
@ -2,6 +2,7 @@ package devices
|
|||
|
||||
import (
|
||||
"log"
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -15,6 +16,7 @@ var _shutdownFuncs []func() error
|
|||
var _devs map[string][]string
|
||||
var _defaults map[string][]string
|
||||
var _startup []func(map[string]string) error
|
||||
var tr lingo.Translations
|
||||
|
||||
// RegisterShutdown stores a function to be called by gotop on exit, allowing
|
||||
// extensions to properly release resources. Extensions should register a
|
||||
|
@ -86,3 +88,7 @@ func Devices(domain string, all bool) []string {
|
|||
}
|
||||
return _defaults[domain]
|
||||
}
|
||||
|
||||
func SetTr(tra lingo.Translations) {
|
||||
tr = tra
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// Code generated by go-bindata.
|
||||
// sources:
|
||||
// data/smc.tsv
|
||||
// DO NOT EDIT!
|
||||
// Code generated by go-bindata. (@generated) DO NOT EDIT.
|
||||
|
||||
//Package devices generated by go-bindata.// sources:
|
||||
// devices/data/smc.tsv
|
||||
package devices
|
||||
|
||||
import (
|
||||
|
@ -20,7 +19,7 @@ import (
|
|||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
@ -28,7 +27,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
|
|||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
|
@ -49,21 +48,32 @@ type bindataFileInfo struct {
|
|||
modTime time.Time
|
||||
}
|
||||
|
||||
// Name return file name
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
|
||||
// Size return file size
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
|
||||
// Mode return file mode
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
|
||||
// ModTime return file modify time
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
|
||||
// IsDir return file whether a directory
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
return fi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
// Sys return file is sys mode
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
@ -83,7 +93,7 @@ func smcTsv() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "smc.tsv", size: 3398, mode: os.FileMode(420), modTime: time.Unix(1591711965, 0)}
|
||||
info := bindataFileInfo{name: "smc.tsv", size: 3398, mode: os.FileMode(420), modTime: time.Unix(1592515411, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -182,6 +192,7 @@ type bintree struct {
|
|||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"smc.tsv": &bintree{smcTsv, map[string]*bintree{}},
|
||||
}}
|
||||
|
@ -232,4 +243,3 @@ func _filePath(dir, name string) string {
|
|||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package devices
|
||||
|
||||
//go:generate go-bindata -pkg devices -prefix data -o smc.go data
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
@ -19,7 +17,7 @@ func UpdateTemps(temps map[string]int) {
|
|||
errs := f(temps)
|
||||
if errs != nil {
|
||||
for k, e := range errs {
|
||||
log.Printf("error updating temp for %s: %s", k, e)
|
||||
log.Printf(tr.Value("error.recovfetch", "temp", k, e.Error()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
func init() {
|
||||
if len(devs()) == 0 {
|
||||
log.Println("temp: no thermal sensors found")
|
||||
log.Println(tr.Value("error.nodevfound", "thermal sensors"))
|
||||
return
|
||||
}
|
||||
RegisterTemp(update)
|
||||
|
@ -58,13 +58,13 @@ func devs() []string {
|
|||
// Check that thermal sensors are really available; they aren't in VMs
|
||||
bs, err := exec.Command("sysctl", "-a").Output()
|
||||
if err != nil {
|
||||
log.Printf("temp: failure to get system information %s", err.Error())
|
||||
log.Printf(tr.Value("error.fatalfetch", "temp", err.Error()))
|
||||
return []string{}
|
||||
}
|
||||
for k, _ := range sensorOIDS {
|
||||
idx := strings.Index(string(bs), k)
|
||||
if idx < 0 {
|
||||
log.Printf("temp: no device %s found", k)
|
||||
log.Printf(tr.Value("error.nodevfound", k))
|
||||
} else {
|
||||
rv = append(rv, k)
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -4,9 +4,11 @@ require (
|
|||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/VictoriaMetrics/metrics v1.11.2
|
||||
github.com/VividCortex/ewma v1.1.1
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||
github.com/distatus/battery v0.9.0
|
||||
github.com/gizak/termui/v3 v3.1.0
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/jdkeke142/lingo-toml v0.0.0-20200705162942-3520fe0dec06
|
||||
github.com/mattn/go-runewidth v0.0.4
|
||||
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1
|
||||
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0
|
||||
|
|
24
go.sum
24
go.sum
|
@ -1,3 +1,5 @@
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VictoriaMetrics/metrics v1.11.2 h1:t/ceLP6SvagUqypCKU7cI7+tQn54+TIV/tGoxihHvx8=
|
||||
|
@ -6,21 +8,21 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc
|
|||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd h1:XtfPmj9tQRilnrEmI1HjQhxXWRhEM+m8CACtaMJE/kM=
|
||||
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:Yg2hDs4b13Evkpj42FU2idX2cVXVFqQSheXYKM86Qsk=
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:MgJyK38wkzZbiZSKeIeFankxxSA8gayko/nr5x5bgBA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/distatus/battery v0.9.0 h1:8NS5o00/j3Oh2xgocA6pQROTp5guoR+s8CZlWzHC4QM=
|
||||
github.com/distatus/battery v0.9.0/go.mod h1:gGO7GxHTi1zlRT+cAj8uGG0/8HFiqAeH0TJvoipnuPs=
|
||||
github.com/gizak/termui/v3 v3.0.0 h1:NYTUG6ig/sJK05O5FyhWemwlVPO8ilNpvS/PgRtrKAE=
|
||||
github.com/gizak/termui/v3 v3.0.0/go.mod h1:uinu2dMdtMI+FTIdEFUJQT5y+KShnhQRshvPblXq3lY=
|
||||
github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
|
||||
github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/jdkeke142/lingo-toml v0.0.0-20200508150411-0ad65ccb786d/go.mod h1:Kji1cjs9t6xDSLWuz6vP6ockOTT1rIdMLnNryfHXVuw=
|
||||
github.com/jdkeke142/lingo-toml v0.0.0-20200705162942-3520fe0dec06 h1:Mzc7Br3CA20ztYUP68pghZgaVTkumWNzgmEAo8etfbE=
|
||||
github.com/jdkeke142/lingo-toml v0.0.0-20200705162942-3520fe0dec06/go.mod h1:Kji1cjs9t6xDSLWuz6vP6ockOTT1rIdMLnNryfHXVuw=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
|
@ -30,32 +32,28 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
|
|||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag=
|
||||
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w=
|
||||
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y=
|
||||
github.com/shirou/gopsutil v2.20.3+incompatible h1:0JVooMPsT7A7HqEYdydp/OfjSOYSjhXV7w1hkKj/NPQ=
|
||||
github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/valyala/fastrand v1.0.0 h1:LUKT9aKer2dVQNUi3waewTbKV+7H17kvWFNKs2ObdkI=
|
||||
github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
|
||||
github.com/valyala/histogram v1.0.1 h1:FzA7n2Tz/wKRMejgu3PV1vw3htAklTjjuoI6z3d4KDg=
|
||||
github.com/valyala/histogram v1.0.1/go.mod h1:lQy0xA4wUz2+IUnf97SivorsJIp8FxsnRd6x25q7Mto=
|
||||
github.com/xxxserxxx/lingo v0.0.0-20200619152803-440e0ec753ec h1:72Kid6wRHf4IZq0oJyJZGo4FuIyJeKqN4n9MEh2l744=
|
||||
github.com/xxxserxxx/lingo v0.0.0-20200619152803-440e0ec753ec/go.mod h1:Kji1cjs9t6xDSLWuz6vP6ockOTT1rIdMLnNryfHXVuw=
|
||||
github.com/xxxserxxx/opflag v1.0.5 h1:2H4Qtl1qe+dSkEcGt+fBe2mQ8z14MgkWPqcLaoa6k90=
|
||||
github.com/xxxserxxx/opflag v1.0.5/go.mod h1:GWZtb3/tGGj5W1GE/JTyJAuqgxDxl1+jqDGAGM+P/p4=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
||||
golang.org/x/sys v0.0.0-20200316230553-a7d97aace0b0 h1:4Khi5GeNOkZS5DqSBRn4Sy7BE6GuxwOqARPqfurkdNk=
|
||||
golang.org/x/sys v0.0.0-20200316230553-a7d97aace0b0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 h1:OKbAoGs4fGM5cPLlVQLZGYkFC8OnOfgo6tt0Smf9XhM=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5 h1:AQkaJpH+/FmqRjmXZPELom5zIERYZfwTjnHpfoVMQEc=
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
|
|
|
@ -3,7 +3,9 @@ package layout
|
|||
import (
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
"github.com/xxxserxxx/gotop/v4"
|
||||
"github.com/xxxserxxx/gotop/v4/widgets"
|
||||
|
||||
|
@ -28,8 +30,10 @@ type MyGrid struct {
|
|||
}
|
||||
|
||||
var widgetNames []string = []string{"cpu", "disk", "mem", "temp", "net", "procs", "batt"}
|
||||
var tr lingo.Translations
|
||||
|
||||
func Layout(wl layout, c gotop.Config) (*MyGrid, error) {
|
||||
tr = c.Tr
|
||||
rowDefs := wl.Rows
|
||||
uiRows := make([][]interface{}, 0)
|
||||
numRows := countNumRows(wl.Rows)
|
||||
|
@ -197,7 +201,7 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
|
|||
b.BarColor = ui.Color(c.Colorscheme.ProcCursor)
|
||||
w = b
|
||||
default:
|
||||
log.Printf("Invalid widget name %s. Must be one of %v", widRule.Widget, widgetNames)
|
||||
log.Printf(tr.Value("layout.error.widget", widRule.Widget, strings.Join(widgetNames, ",")))
|
||||
return ui.NewBlock()
|
||||
}
|
||||
if c.ExportPort != "" {
|
||||
|
|
|
@ -83,7 +83,8 @@ func ParseLayout(i io.Reader) layout {
|
|||
if len(rs) > 1 {
|
||||
v, e := strconv.Atoi(rs[0])
|
||||
if e != nil {
|
||||
log.Printf("Layout error on line %d: format must be INT:STRING/INT. Error parsing %s as a int. Word was %s. Using a row height of 1.", lineNo, rs[0], w)
|
||||
ln := strconv.Itoa(lineNo)
|
||||
log.Printf(tr.Value("layout.error.format", "INT:STRING/INT", ln, rs[0], w))
|
||||
v = 1
|
||||
}
|
||||
if v < 1 {
|
||||
|
@ -99,7 +100,8 @@ func ParseLayout(i io.Reader) layout {
|
|||
if len(ks) > 1 {
|
||||
weight, e := strconv.Atoi(ks[1])
|
||||
if e != nil {
|
||||
log.Printf("Layout error on line %d: format must be STRING/INT. Error parsing %s as a int. Word was %s. Using a weight of 1 for widget.", lineNo, ks[1], w)
|
||||
ln := strconv.Itoa(lineNo)
|
||||
log.Printf(tr.Value("layout.error.format", "STRING/INT", ln, ks[1], w))
|
||||
weight = 1
|
||||
}
|
||||
if weight < 1 {
|
||||
|
@ -107,7 +109,8 @@ func ParseLayout(i io.Reader) layout {
|
|||
}
|
||||
wr.Weight = float64(weight)
|
||||
if len(ks) > 2 {
|
||||
log.Printf("Layout warning on line %d: too many '/' in word %s; ignoring extra junk.", lineNo, w)
|
||||
ln := strconv.Itoa(lineNo)
|
||||
log.Printf(tr.Value("layout.error.slashes", ln, w))
|
||||
}
|
||||
weightTotal += weight
|
||||
} else {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
"github.com/xxxserxxx/gotop/v4"
|
||||
)
|
||||
|
||||
|
@ -29,6 +30,7 @@ func New(c gotop.Config) (io.WriteCloser, error) {
|
|||
w := &RotateWriter{
|
||||
filename: filepath.Join(cache.Path, LOGFILE),
|
||||
maxLogSize: c.MaxLogSize,
|
||||
tr: c.Tr,
|
||||
}
|
||||
err = w.rotate()
|
||||
if err != nil {
|
||||
|
@ -48,6 +50,7 @@ type RotateWriter struct {
|
|||
filename string // should be set to the actual filename
|
||||
fp *os.File
|
||||
maxLogSize int64
|
||||
tr lingo.Translations
|
||||
}
|
||||
|
||||
func (w *RotateWriter) Close() error {
|
||||
|
@ -103,7 +106,7 @@ func (w *RotateWriter) rotate() (err error) {
|
|||
// open the log file
|
||||
w.fp, err = os.OpenFile(w.filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0660)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open log file %s: %v", w.filename, err)
|
||||
return fmt.Errorf(w.tr.Value("error.logopen", w.filename, err.Error()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -5,8 +5,10 @@ import (
|
|||
"image"
|
||||
"log"
|
||||
"strings"
|
||||
"strconv"
|
||||
|
||||
. "github.com/gizak/termui/v3"
|
||||
"github.com/jdkeke142/lingo-toml"
|
||||
)
|
||||
|
||||
type Table struct {
|
||||
|
@ -30,6 +32,8 @@ type Table struct {
|
|||
TopRow int // used to indicate where in the table we are scrolled at
|
||||
|
||||
ColResizer func()
|
||||
|
||||
Tr lingo.Translations
|
||||
}
|
||||
|
||||
// NewTable returns a new Table instance
|
||||
|
@ -79,7 +83,8 @@ func (self *Table) Draw(buf *Buffer) {
|
|||
}
|
||||
|
||||
if self.TopRow < 0 {
|
||||
log.Printf("table widget TopRow value less than 0. TopRow: %v", self.TopRow)
|
||||
r := strconv.Itoa(self.TopRow)
|
||||
log.Printf(self.Tr.Value("error.table", r))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
404
translations/dicts.go
Normal file
404
translations/dicts.go
Normal file
File diff suppressed because one or more lines are too long
180
translations/dicts/de_DE.toml
Normal file
180
translations/dicts/de_DE.toml
Normal file
|
@ -0,0 +1,180 @@
|
|||
configfile="Config file"
|
||||
usage="Usage: {0} [options]\n\nOptions:\n"
|
||||
total="Total"
|
||||
|
||||
|
||||
[help]
|
||||
paths="Loadable colorschemes & layouts, and the config file, are searched for, in order:"
|
||||
log="The log file is in {0}"
|
||||
written="Config written to {0}"
|
||||
help="""
|
||||
Quit: q or <C-c>
|
||||
|
||||
Process navigation:
|
||||
- k and <Up>: up
|
||||
- j and <Down>: down
|
||||
- <C-u>: half page up
|
||||
- <C-d>: half page down
|
||||
- <C-b>: full page up
|
||||
- <C-f>: full page down
|
||||
- gg and <Home>: jump to top
|
||||
- G and <End>: jump to bottom
|
||||
|
||||
Process actions:
|
||||
- <Tab>: toggle process grouping
|
||||
- dd: kill selected process or group of processes with SIGTERM (15)
|
||||
- d3: kill selected process or group of processes with SIGQUIT (3)
|
||||
- d9: kill selected process or group of processes with SIGKILL (9)
|
||||
|
||||
Process sorting:
|
||||
- c: CPU
|
||||
- m: Mem
|
||||
- p: PID
|
||||
|
||||
Process filtering:
|
||||
- /: start editing filter
|
||||
- (while editing):
|
||||
- <Enter>: accept filter
|
||||
- <C-c> and <Escape>: clear filter
|
||||
|
||||
CPU and Mem graph scaling:
|
||||
- h: scale in
|
||||
- l: scale out
|
||||
|
||||
Network:
|
||||
- b: toggle between mbps and scaled bytes per second
|
||||
"""
|
||||
# TRANSLATORS: Please don't translate the layout **names**
|
||||
layouts = """Built-in layouts:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink"""
|
||||
# TRANSLATORS: Please don't translate the colorcheme **names**
|
||||
colorschemes = """Built-in colorschemes:
|
||||
default
|
||||
default-dark (for white background)
|
||||
solarized
|
||||
solarized16-dark
|
||||
solarized16-light
|
||||
monokai
|
||||
vice"""
|
||||
# TRANSLATORS: Please don't translate the widget **names**
|
||||
widgets = """Widgets that can be used in layouts:
|
||||
cpu - CPU load graph
|
||||
mem - Physical & swap memory use graph
|
||||
temp - Sensor temperatures
|
||||
disk - Physical disk partition use
|
||||
power - A battery bar
|
||||
net - Network load
|
||||
procs - Interactive process list"""
|
||||
|
||||
|
||||
[args]
|
||||
help="Hilfetext anzeigen."
|
||||
color="Ein Farbschema feststellen."
|
||||
scale="Stellen den Skalierungsfaktor ein, >0"
|
||||
version="Zeigen die Version aus und beenden."
|
||||
percpu="Show each CPU in the CPU widget."
|
||||
cpuavg="Show average CPU in the CPU widget."
|
||||
temp="Show temperatures in fahrenheit.Show temperatures in fahrenheit."
|
||||
statusbar="Show a statusbar with the time."
|
||||
rate="Refresh frequency. Most time units accepted. \"1m\" = refresh every minute. \"100ms\" = refresh every 100ms."
|
||||
layout="Name of layout spec file for the UI. Use \"-\" to pipe."
|
||||
net="Select network interface. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using \"!\""
|
||||
export="Enable metrics for export on the specified port."
|
||||
mbps="Show network rate as mbps."
|
||||
test="Runs tests and exits with success/failure code."
|
||||
conffile="Config file to use instead of default (MUST BE FIRST ARGUMENT)"
|
||||
list="""
|
||||
List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: Prints out device names for filterable widgets
|
||||
layouts: Lists build-in layouts
|
||||
colorschemes: Lists built-in colorschemes
|
||||
paths: List out configuration file search paths
|
||||
widgets: Widgets that can be used in a layout
|
||||
keys: Show the keyboard bindings."""
|
||||
write="Write out a default config file."
|
||||
|
||||
|
||||
[config.err]
|
||||
configsyntax="0| bad config file syntax; should be KEY=VALUE, was {0}"
|
||||
deprecation="1| line {0}: '{1}' is deprecated. Ignored {1}={2}"
|
||||
line="2| line #{0}: {1}"
|
||||
tempscale="3| invalid TempScale value {0}"
|
||||
|
||||
|
||||
[error]
|
||||
configparse="4| failed to parse config file: {0}"
|
||||
cliparse="5| parsing CLI args: {0}"
|
||||
logsetup="6| failed to setup log file: {0}"
|
||||
unknownopt="7| Unknown option \"{0}\"; try layouts, colorschemes, keys, paths, or devices\n"
|
||||
writefail="8| Failed to write configuration file: {0}"
|
||||
checklog="9| errors encountered; from {0}:"
|
||||
metricsetup="10| error setting up {0} metrics: {1}"
|
||||
nometrics="11| no metrics for {0} {1}"
|
||||
fatalfetch="12| fatal error fetching {0} info: {1}"
|
||||
recovfetch="13| recoverable error fetching {0} info; skipping {0}: {1}"
|
||||
nodevfound="14| no usable {0} found"
|
||||
setuperr="15| error setting up {0}: {1}"
|
||||
colorschemefile="16| failed to find colorscheme file {0} in {1}"
|
||||
colorschemeread="17| failed to read colorscheme file {0}: {1}"
|
||||
colorschemeparse="18| failed to parse colorscheme file: {0}"
|
||||
findlayout="19| failed to read colorscheme file {0}: {1}"
|
||||
logopen="20| failed to open log file {0}: {1}"
|
||||
table="21| table widget TopRow value less than 0. TopRow: {0}"
|
||||
nohostname="22| could not get hostname: {0}"
|
||||
|
||||
[layout.error]
|
||||
widget="23| Invalid widget name {0}. Must be one of {1}"
|
||||
format="24| Layout error on line {0}: format must be {1}. Error parsing {2} as a int. Word was {3}. Using a row height of 1."
|
||||
slashes="25| Layout warning on line {0}: too many '/' in word {1}; ignoring extra junk."
|
||||
|
||||
[widget.label]
|
||||
disk=" Disk Usage "
|
||||
cpu=" CPU Usage "
|
||||
gauge=" Power Level "
|
||||
battery=" Battery Status "
|
||||
batt=" Battery "
|
||||
temp=" Temperatures "
|
||||
net=" Network Usage "
|
||||
netint=" Network Usage: {0} "
|
||||
mem=" Memory Usage "
|
||||
|
||||
|
||||
[widget.net.err]
|
||||
netactivity="26| failed to get network activity from gopsutil: {0}"
|
||||
negvalrecv="27| error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}"
|
||||
negvalsent="28| error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}"
|
||||
|
||||
|
||||
[widget.disk]
|
||||
disk="Disk"
|
||||
mount="Mount"
|
||||
used="Used"
|
||||
free="Free"
|
||||
rs="R/s"
|
||||
ws="W/s"
|
||||
|
||||
|
||||
[widget.proc]
|
||||
filter=" Filter: "
|
||||
label=" Processes "
|
||||
[widget.proc.header]
|
||||
count="Count"
|
||||
command="Command"
|
||||
cpu="CPU%"
|
||||
mem="Mem%"
|
||||
pid="PID"
|
||||
[widget.proc.err]
|
||||
count="29| failed to get CPU count from gopsutil: {0}"
|
||||
retrieve="30| failed to retrieve processes: {0}"
|
||||
ps="31| failed to execute 'ps' command: {0}"
|
||||
gopsutil="32| failed to get processes from gopsutil: {0}"
|
||||
pidconv="33| failed to convert PID to int: {0}. line: {1}"
|
||||
cpuconv="34| failed to convert CPU usage to float: {0}. line: {1}"
|
||||
memconv="35| failed to convert Mem usage to float: {0}. line: {1}"
|
||||
getcmd="36| failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
cpupercent="37| failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
mempercent="38| failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
parse="39| failed to parse output: {0}"
|
180
translations/dicts/en_US.toml
Normal file
180
translations/dicts/en_US.toml
Normal file
|
@ -0,0 +1,180 @@
|
|||
configfile="Config file"
|
||||
usage="Usage: {0} [options]\n\nOptions:\n"
|
||||
total="Total"
|
||||
|
||||
|
||||
[help]
|
||||
paths="Loadable colorschemes & layouts, and the config file, are searched for, in order:"
|
||||
log="The log file is in {0}"
|
||||
written="Config written to {0}"
|
||||
help="""
|
||||
Quit: q or <C-c>
|
||||
|
||||
Process navigation:
|
||||
- k and <Up>: up
|
||||
- j and <Down>: down
|
||||
- <C-u>: half page up
|
||||
- <C-d>: half page down
|
||||
- <C-b>: full page up
|
||||
- <C-f>: full page down
|
||||
- gg and <Home>: jump to top
|
||||
- G and <End>: jump to bottom
|
||||
|
||||
Process actions:
|
||||
- <Tab>: toggle process grouping
|
||||
- dd: kill selected process or group of processes with SIGTERM (15)
|
||||
- d3: kill selected process or group of processes with SIGQUIT (3)
|
||||
- d9: kill selected process or group of processes with SIGKILL (9)
|
||||
|
||||
Process sorting:
|
||||
- c: CPU
|
||||
- m: Mem
|
||||
- p: PID
|
||||
|
||||
Process filtering:
|
||||
- /: start editing filter
|
||||
- (while editing):
|
||||
- <Enter>: accept filter
|
||||
- <C-c> and <Escape>: clear filter
|
||||
|
||||
CPU and Mem graph scaling:
|
||||
- h: scale in
|
||||
- l: scale out
|
||||
|
||||
Network:
|
||||
- b: toggle between mbps and scaled bytes per second
|
||||
"""
|
||||
# TRANSLATORS: Please don't translate the layout **names**
|
||||
layouts = """Built-in layouts:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink"""
|
||||
# TRANSLATORS: Please don't translate the colorcheme **names**
|
||||
colorschemes = """Built-in colorschemes:
|
||||
default
|
||||
default-dark (for white background)
|
||||
solarized
|
||||
solarized16-dark
|
||||
solarized16-light
|
||||
monokai
|
||||
vice"""
|
||||
# TRANSLATORS: Please don't translate the widget **names**
|
||||
widgets = """Widgets that can be used in layouts:
|
||||
cpu - CPU load graph
|
||||
mem - Physical & swap memory use graph
|
||||
temp - Sensor temperatures
|
||||
disk - Physical disk partition use
|
||||
power - A battery bar
|
||||
net - Network load
|
||||
procs - Interactive process list"""
|
||||
|
||||
|
||||
[args]
|
||||
help="Show this screen."
|
||||
color="Set a colorscheme."
|
||||
scale="Graph scale factor, >0"
|
||||
version="Print version and exit."
|
||||
percpu="Show each CPU in the CPU widget."
|
||||
cpuavg="Show average CPU in the CPU widget."
|
||||
temp="Show temperatures in fahrenheit.Show temperatures in fahrenheit."
|
||||
statusbar="Show a statusbar with the time."
|
||||
rate="Refresh frequency. Most time units accepted. \"1m\" = refresh every minute. \"100ms\" = refresh every 100ms."
|
||||
layout="Name of layout spec file for the UI. Use \"-\" to pipe."
|
||||
net="Select network interface. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using \"!\""
|
||||
export="Enable metrics for export on the specified port."
|
||||
mbps="Show network rate as mbps."
|
||||
test="Runs tests and exits with success/failure code."
|
||||
conffile="Config file to use instead of default (MUST BE FIRST ARGUMENT)"
|
||||
list="""
|
||||
List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: Prints out device names for filterable widgets
|
||||
layouts: Lists build-in layouts
|
||||
colorschemes: Lists built-in colorschemes
|
||||
paths: List out configuration file search paths
|
||||
widgets: Widgets that can be used in a layout
|
||||
keys: Show the keyboard bindings."""
|
||||
write="Write out a default config file."
|
||||
|
||||
|
||||
[config.err]
|
||||
configsyntax="0| bad config file syntax; should be KEY=VALUE, was {0}"
|
||||
deprecation="1| line {0}: '{1}' is deprecated. Ignored {1}={2}"
|
||||
line="2| line #{0}: {1}"
|
||||
tempscale="3| invalid TempScale value {0}"
|
||||
|
||||
|
||||
[error]
|
||||
configparse="4| failed to parse config file: {0}"
|
||||
cliparse="5| parsing CLI args: {0}"
|
||||
logsetup="6| failed to setup log file: {0}"
|
||||
unknownopt="7| Unknown option \"{0}\"; try layouts, colorschemes, keys, paths, or devices\n"
|
||||
writefail="8| Failed to write configuration file: {0}"
|
||||
checklog="9| errors encountered; from {0}:"
|
||||
metricsetup="10| error setting up {0} metrics: {1}"
|
||||
nometrics="11| no metrics for {0} {1}"
|
||||
fatalfetch="12| fatal error fetching {0} info: {1}"
|
||||
recovfetch="13| recoverable error fetching {0} info; skipping {0}: {1}"
|
||||
nodevfound="14| no usable {0} found"
|
||||
setuperr="15| error setting up {0}: {1}"
|
||||
colorschemefile="16| failed to find colorscheme file {0} in {1}"
|
||||
colorschemeread="17| failed to read colorscheme file {0}: {1}"
|
||||
colorschemeparse="18| failed to parse colorscheme file: {0}"
|
||||
findlayout="19| failed to read colorscheme file {0}: {1}"
|
||||
logopen="20| failed to open log file {0}: {1}"
|
||||
table="21| table widget TopRow value less than 0. TopRow: {0}"
|
||||
nohostname="22| could not get hostname: {0}"
|
||||
|
||||
[layout.error]
|
||||
widget="23| Invalid widget name {0}. Must be one of {1}"
|
||||
format="24| Layout error on line {0}: format must be {1}. Error parsing {2} as a int. Word was {3}. Using a row height of 1."
|
||||
slashes="25| Layout warning on line {0}: too many '/' in word {1}; ignoring extra junk."
|
||||
|
||||
[widget.label]
|
||||
disk=" Disk Usage "
|
||||
cpu=" CPU Usage "
|
||||
gauge=" Power Level "
|
||||
battery=" Battery Status "
|
||||
batt=" Battery "
|
||||
temp=" Temperatures "
|
||||
net=" Network Usage "
|
||||
netint=" Network Usage: {0} "
|
||||
mem=" Memory Usage "
|
||||
|
||||
|
||||
[widget.net.err]
|
||||
netactivity="26| failed to get network activity from gopsutil: {0}"
|
||||
negvalrecv="27| error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}"
|
||||
negvalsent="28| error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}"
|
||||
|
||||
|
||||
[widget.disk]
|
||||
disk="Disk"
|
||||
mount="Mount"
|
||||
used="Used"
|
||||
free="Free"
|
||||
rs="R/s"
|
||||
ws="W/s"
|
||||
|
||||
|
||||
[widget.proc]
|
||||
filter=" Filter: "
|
||||
label=" Processes "
|
||||
[widget.proc.header]
|
||||
count="Count"
|
||||
command="Command"
|
||||
cpu="CPU%"
|
||||
mem="Mem%"
|
||||
pid="PID"
|
||||
[widget.proc.err]
|
||||
count="29| failed to get CPU count from gopsutil: {0}"
|
||||
retrieve="30| failed to retrieve processes: {0}"
|
||||
ps="31| failed to execute 'ps' command: {0}"
|
||||
gopsutil="32| failed to get processes from gopsutil: {0}"
|
||||
pidconv="33| failed to convert PID to int: {0}. line: {1}"
|
||||
cpuconv="34| failed to convert CPU usage to float: {0}. line: {1}"
|
||||
memconv="35| failed to convert Mem usage to float: {0}. line: {1}"
|
||||
getcmd="36| failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
cpupercent="37| failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
mempercent="38| failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
parse="39| failed to parse output: {0}"
|
182
translations/dicts/eo.toml
Normal file
182
translations/dicts/eo.toml
Normal file
|
@ -0,0 +1,182 @@
|
|||
configfile="Argododosiero"
|
||||
usage="Uzado: {0} [ebloj]\n\nEbloj:\n"
|
||||
total="Sumo"
|
||||
|
||||
|
||||
[help]
|
||||
paths="Ŝarĝebla kloraj skemoj & enpaĝigoj, kaj la argododosiero, estas orda serĉatigis:"
|
||||
log="Logodosiero troviĝas ĉe {0}"
|
||||
written="Argordo skribiĝis ĉe {0}"
|
||||
help="""
|
||||
Eliri: q aŭ <C-c>
|
||||
|
||||
Proceza navigadoj:
|
||||
- k kaj <Supren>: supren
|
||||
- j kaj <Malsupren>: malsupren
|
||||
- <C-u>: duona paĝo supren
|
||||
- <C-d>: duona paĝo malsupren
|
||||
- <C-b>: plena paĝo supren
|
||||
- <C-f>: plena paĝo malsupren
|
||||
- gg kaj <Hejmo>: salti al supron
|
||||
- G kaj <Fino>: salti al malsupron
|
||||
|
||||
Proceza agoj:
|
||||
- <Langeto>: alterni procezon grupigi
|
||||
- dd: fini la elektitajn procezojn aŭ procezon grupigon kun SIGTERM (15)
|
||||
- d3: fini la elektitajn procezojn aŭ procezon grupigon kun SIGQUIT (3)
|
||||
- d9: fini la elektitajn procezojn aŭ procezon grupigon kun SIGKILL (9)
|
||||
|
||||
Proceza ordigoj:
|
||||
- c: CPU
|
||||
- m: Memoro
|
||||
- p: PID
|
||||
|
||||
Proceza filtradoj:
|
||||
- /: komenci redakti filtrilon
|
||||
- (dum redaktadi):
|
||||
- <Eniri>: akcepti filtrilon
|
||||
- <C-c> kaj <Eskapi>: eliri filtrilon
|
||||
|
||||
CPU kaj Memora grafilo skali:
|
||||
- h: zomi
|
||||
- l: malzomi
|
||||
|
||||
Reto:
|
||||
- b: alterni inter mbps kaj skale bajtoj por dua
|
||||
"""
|
||||
# TRANSLATORS: Please don't translate the layout **names**
|
||||
layouts = """Enkonstruitaj enpaĝigoj:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink"""
|
||||
# TRANSLATORS: Please don't translate the colorscheme **names**
|
||||
colorschemes = """Enkonstruitaj kloraj skemoj:
|
||||
default
|
||||
default-dark (por blanka fono)
|
||||
solarized
|
||||
solarized16-dark
|
||||
solarized16-light
|
||||
monokai
|
||||
vice"""
|
||||
# TRANSLATORS: Please don't translate the widget **names**
|
||||
widgets = """Enpaĝigaj Fenestraĵoj:
|
||||
cpu - CPU ŝarĝa grafilo
|
||||
mem - Fizika kay interŝanĝa memora grafilo
|
||||
temp - Temperatura sensiloj
|
||||
disk - Fizikaj diskdispartigaj uzadilo
|
||||
power - Bateria mezurilo
|
||||
net - Retuzadilo
|
||||
procs - Interaga proceza listo"""
|
||||
|
||||
|
||||
[args]
|
||||
help="Ĉi tiun informoj."
|
||||
color="Agordi kloraj skemoj."
|
||||
scale="Agordi grafilan skalon, >0"
|
||||
version="Montri version kaj eliri."
|
||||
percpu="Montri ĉiun CPU en la CPU-fenestraĵo."
|
||||
cpuavg="Montri duonan CPU en la CPU-fenestraĵo."
|
||||
temp="Montri temperaturojn en fahrenheit."
|
||||
statusbar="Montri statusbarbaron kun la tempo."
|
||||
rate="Refreŝiga ofteco. Plej multaj unuoj akceptitaj. \"1m\" = refreŝigi ĉiun minuton. \"100ms\" = refreŝigi ĉiun dekonon minuton."
|
||||
layout="Nomo de aranĝa specifa dosiero por la UI. Uzu \"-\" por pipi."
|
||||
net="Elekti retinterfacon. Multaj interfacoj povas esti difinitaj per komparaj valoroj. Interfacoj ankaŭ povas esti ignorataj per \"!\""
|
||||
export="Ebligu metrikojn por eksportado en la specifita haveno."
|
||||
mbps="Montri reta takson kiel mbps."
|
||||
test="Ekzekutas testojn kaj forirojn kun sukceso / fiaska kodo."
|
||||
conffile="Agordi dosiero por uzi anstataŭ defaŭlte (DEVAS ESTI UNUA ARGUMENTO)"
|
||||
# TRANSLATORS: Please don't translate the list entries
|
||||
list="""
|
||||
List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: Montras nomojn de aparatoj por filteblaj fenestraĵoj
|
||||
layouts: Listigas enkonstruajn aranĝojn
|
||||
colorschemes: Listas enkonstruitajn kloraj skemoj
|
||||
paths: Enlistigu agordajn serĉajn vojojn de agordo
|
||||
widgets: Fenestraĵoj uzeblaj en aranĝo
|
||||
keys: Montri la klavarajn ligojn."""
|
||||
write="Skribu defaŭltan agordan dosieron."
|
||||
|
||||
|
||||
[config.err]
|
||||
configsyntax="0| malbona agordo dosiero-sintakso; estu ŜLOSI=VALORO, estis {0}"
|
||||
deprecation="1| linio {0}: '{1}' malakceptas. Ignorita {1}={2}"
|
||||
line="2| linio #{0}: {1}"
|
||||
tempscale="3| malvalida TempScale-valoro {0}"
|
||||
|
||||
|
||||
[error]
|
||||
configparse="4| malsukcesis pari agordi dosiero: {0}"
|
||||
cliparse="5| analizante CLI-argumentojn: {0}"
|
||||
logsetup="6| malsukcesis agordi registro dosiero: {0}"
|
||||
unknownopt="7| Nekonata opcio \"{0}\"; provu layouts, colorschemes, keys, paths, aŭ devices"
|
||||
writefail="8| Malsukcesis skribi agordan dosieron: {0}"
|
||||
checklog="9| eraroj renkontitaj; de {0}:"
|
||||
metricsetup="10| eraro agordante {0} metrikojn: {1}"
|
||||
nometrics="11| neniuj metrikoj por {0} {1}"
|
||||
fatalfetch="12| fatala eraro elprenanta {0} info: {1}"
|
||||
recovfetch="13| reakirebla eraro elprenanta {0} info; saltante {0}: {1}"
|
||||
nodevfound="14| neniu uzebla {0} trovita"
|
||||
setuperr="15| eraro agordante {0}: {1}"
|
||||
colorschemefile="16| malsukcesis trovi kloraj skemoj dosiero {0} en {1}"
|
||||
colorschemeread="17| malsukcesis legi kloraj skemoj dosiero {0}: {1}"
|
||||
colorschemeparse="18| Fiaskis analizi kloraj skemoj dosiero: {0}"
|
||||
findlayout="19| malsukcesis legi kloraj skemoj dosiero {0}: {1}"
|
||||
logopen="20| malsukcesis malfermi enskribi dosieron {0}: {1}"
|
||||
table="21| Tabla fenestraĵo TopRow-valoro malpli ol 0. TopRow: {0}"
|
||||
nohostname="22| Ne povis akiri hostname: {0}"
|
||||
|
||||
[layout.error]
|
||||
widget="23| Malvalida fenestra nomo {0}. Devas esti unu el {1}"
|
||||
format="24| Eraro pri aranĝo sur linio {0}: formato devas esti {1}. Eraro analizante {2} kiel int. Vorto estis {3}. Uzante vicon alteco de 1."
|
||||
slashes="25| Averto pri aranĝo sur linio {0}: tro multaj '/' en vorto {1}; ignorante kroman rubon."
|
||||
|
||||
[widget.label]
|
||||
disk=" Disk Usado "
|
||||
cpu=" CPU Usado "
|
||||
gauge=" Potencnivelo "
|
||||
battery=" Bateria Statuso "
|
||||
batt=" Baterio "
|
||||
temp=" Temperaturoj "
|
||||
net=" Reta Usado "
|
||||
netint=" Reta Usado: {0} "
|
||||
mem=" Memoro Usado "
|
||||
|
||||
|
||||
[widget.net.err]
|
||||
netactivity="26| malsukcesis ricevi retactiveco de gopsutil: {0}"
|
||||
negvalrecv="27| eraro: negativa valoro por ĵus ricevitaj retdatumoj de gopsutil. RecentBytesRecv: {0}"
|
||||
negvalsent="28| eraro: negativa valoro por ĵus senditaj retdatumoj de gopsutil. RecentBytesSent: {0}"
|
||||
|
||||
|
||||
[widget.disk]
|
||||
disk="Disko"
|
||||
mount="Monto"
|
||||
used="Uzita"
|
||||
free="Senpaga"
|
||||
rs="R/s"
|
||||
ws="W/s"
|
||||
|
||||
|
||||
[widget.proc]
|
||||
filter=" Filtrilo: "
|
||||
label=" Procezoj "
|
||||
[widget.proc.header]
|
||||
count="Kalkulo"
|
||||
command="Komando"
|
||||
cpu="CPU%"
|
||||
mem="Mem%"
|
||||
pid="PID"
|
||||
|
||||
[widget.proc.err]
|
||||
count="29| malsukcesis akiri CPU-kalkuladon de gopsutil: {0}"
|
||||
retrieve="30| ne sukcesis akiri procezojn: {0}"
|
||||
ps="31| malsukcesis plenumi komandon 'ps': {0}"
|
||||
gopsutil="32| malsukcesis akiri procezojn de gopsutilo: {0}"
|
||||
pidconv="33| malsukcesis konverti PID al int: {0}. linio: {1}"
|
||||
cpuconv="34| malsukcesis konverti CPU-uzon al flosilo: {0}. linio: {1}"
|
||||
memconv="35| malsukcesis konverti Mem-uzon al flosilo: {0}. linio: {1}"
|
||||
getcmd="36| malsukcesis akiri procezan komandon de gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
cpupercent="37| malsukcesis ricevi uzadon de proceso cpu de gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
mempercent="38| malsukcesis ricevi uzadon de proceza memoro de gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
parse="39| ne sukcesis analizi eliron: {0}"
|
180
translations/dicts/tt_TT.toml
Normal file
180
translations/dicts/tt_TT.toml
Normal file
|
@ -0,0 +1,180 @@
|
|||
configfile="CFG FLE"
|
||||
usage="egasU: {0} [snoitpo]\n\nsnoitpO:\n"
|
||||
total="latoT"
|
||||
|
||||
|
||||
[help]
|
||||
paths="redro ni ,rof dehcraes era ,elif gifnoc eht dna ,stuoyal & semehcsroloc elbadaoL:"
|
||||
log="ni si elif gol ehT {0}"
|
||||
written="ot nettirw gifnoC {0}"
|
||||
help="""
|
||||
>c-C< ro q :tiuQ
|
||||
|
||||
:noitagivan ssecorP
|
||||
pu :>pU< dna k -
|
||||
nwod :>nwoD< dna j -
|
||||
pu egap flah :>u-C< -
|
||||
nwod egap flah :>d-C< -
|
||||
pu egap lluf :>b-C< -
|
||||
nwod egap lluf :>f-C< -
|
||||
pot ot pmuj :>emoH< dna gg -
|
||||
mottob ot pmuj :>dnE< dna G -
|
||||
|
||||
:snoitca ssecorP
|
||||
gnipuorg ssecorp elggot :>baT< -
|
||||
)51( MRETGIS htiw sessecorp fo puorg ro ssecorp detceles llik :dd -
|
||||
)3( TIUQGIS htiw sessecorp fo puorg ro ssecorp detceles llik :3d -
|
||||
)9( LLIKGIS htiw sessecorp fo puorg ro ssecorp detceles llik :9d -
|
||||
|
||||
:gnitros ssecorP
|
||||
UPC :c -
|
||||
meM :m -
|
||||
DIP :p -
|
||||
|
||||
:gniretlif ssecorP
|
||||
retlif gnitide trats :/ -
|
||||
:)gnitide elihw( -
|
||||
retlif tpecca :>retnE< -
|
||||
retlif raelc :>epacsE< dna >c-C< -
|
||||
|
||||
:gnilacs hparg meM dna UPC
|
||||
ni elacs :h -
|
||||
tuo elacs :l -
|
||||
|
||||
:krowteN
|
||||
dnoces rep setyb delacs dna spbm neewteb elggot :b -
|
||||
"""
|
||||
# TRANSLATORS: Please don't translate the layout **names**
|
||||
layouts = """stuoyal ni-tliuB:
|
||||
tluafed
|
||||
laminim
|
||||
yrettab
|
||||
knisnehctik"""
|
||||
# TRANSLATORS: Please don't translate the colorcheme **names**
|
||||
colorschemes = """semehcsroloc ni-tliuB:
|
||||
tluafed
|
||||
)dnuorgkcab etihw rof( krad-tluafed
|
||||
deziralos
|
||||
krad-61deziralos
|
||||
thgil-61deziralos
|
||||
iakonom
|
||||
eciv"""
|
||||
# TRANSLATORS: Please don't translate the widget **names**
|
||||
widgets = """stuoyal ni desu eb nac taht stegdiW:
|
||||
hparg daol UPC - upc
|
||||
hparg esu yromem paws & lacisyhP - mem
|
||||
serutarepmet rosneS - pmet
|
||||
esu noititrap ksid lacisyhP - ksid
|
||||
rab yrettab A - rewop
|
||||
daol krowteN - ten
|
||||
tsil ssecorp evitcaretnI - scorp"""
|
||||
|
||||
|
||||
[args]
|
||||
help=".neercs siht wohS"
|
||||
color=".emehcsroloc a teS"
|
||||
scale="0> ,rotcaf elacs hparG"
|
||||
version=".tixe dna noisrev tnirP"
|
||||
percpu=".tegdiw UPC eht ni UPC hcae wohS"
|
||||
cpuavg=".tegdiw UPC eht ni UPC egareva wohS"
|
||||
temp=".tiehnerhaf ni serutarepmet wohS.tiehnerhaf ni serutarepmet wohS"
|
||||
statusbar=".emit eht htiw rabsutats a wohS"
|
||||
rate=".sm001 yreve hserfer = \"sm001\" .etunim yreve hserfer = \"m1\" .detpecca stinu emit tsoM .ycneuqerf hserfeR"
|
||||
layout="Name of layout spec file for the UI. Use \"-\" to pipe."
|
||||
net="gnisu derongi eb osla nac secafretnI .seulav detarapes ammoc gnisu denifed eb nac secafretni lareveS .ecafretni krowten tceleS \"!\""
|
||||
export=".trop deificeps eht no tropxe rof scirtem elbanE"
|
||||
mbps=".spbm sa etar krowten wohS"
|
||||
test=".edoc eruliaf/sseccus htiw stixe dna stset snuR"
|
||||
conffile=")TNEMUGRA TSRIF EB TSUM( tluafed fo daetsni esu ot elif gifnoC"
|
||||
list="""
|
||||
>syek|shtap|semehcsroloc|stuoyal|secived< tsiL
|
||||
stegdiw elbaretlif rof seman ecived tuo stnirP :secived
|
||||
stuoyal ni-dliub stsiL :stuoyal
|
||||
semehcsroloc ni-tliub stsiL :semehcsroloc
|
||||
shtap hcraes elif noitarugifnoc tuo tsiL :shtap
|
||||
tuoyal a ni desu eb nac taht stegdiW :stegdiw
|
||||
.sgnidnib draobyek eht wohS :syek """
|
||||
write=".elif gifnoc tluafed a tuo etirW"
|
||||
|
||||
|
||||
[config.err]
|
||||
configsyntax="0| saw ,EULAV=YEK eb dluohs ;xatnys elif gifnoc dab {0}"
|
||||
deprecation="1| enil {0}: '{1}' derongI .detacerped si {1}={2}"
|
||||
line="2| enil #{0}: {1}"
|
||||
tempscale="3| eulav elacSpmeT dilavni {0}"
|
||||
|
||||
|
||||
[error]
|
||||
configparse="4| elif gifnoc esrap ot deliaf: {0}"
|
||||
cliparse="8| sgra ILC gnisrap: {0}"
|
||||
logsetup="9| elif gol putes ot deliaf: {0}"
|
||||
unknownopt="10| noitpo nwonknU \"{0}\"; secived ro ,shtap ,syek ,semehcsroloc ,stuoyal yrt\n"
|
||||
writefail="11| elif noitarugifnoc etirw ot deliaF: {0}"
|
||||
checklog="12| morf ;deretnuocne srorre {0}:"
|
||||
metricsetup="13| pu gnittes rorre {0} scirtem: {1}"
|
||||
nometrics="14| rof scirtem on {0} {1}"
|
||||
fatalfetch="15| gnihctef rorre lataf {0} ofni: {1}"
|
||||
recovfetch="16| gnihctef rorre elbarevocer {0} gnippiks ;ofni {0}: {1}"
|
||||
nodevfound="17| elbasu on {0} dnuof"
|
||||
setuperr="18| pu gnittes rorre {0}: {1}"
|
||||
colorschemefile="19| elif emehcsroloc dnif ot deliaf {0} ni {1}"
|
||||
colorschemeread="20| elif emehcsroloc daer ot deliaf {0}: {1}"
|
||||
colorschemeparse="21| elif emehcsroloc esrap ot deliaf: {0}"
|
||||
findlayout="22| elif emehcsroloc daer ot deliaf {0}: {1}"
|
||||
logopen="22| elif gol nepo ot deliaf {0}: {1}"
|
||||
table="22| woRpoT .0 naht ssel eulav woRpoT tegdiw elbat: {0}"
|
||||
nohostname="22| emantsoh teg ton dluoc: {0}"
|
||||
|
||||
[layout.error]
|
||||
widget="23| eman tegdiw dilavnI {0}. fo eno eb tsuM {1}"
|
||||
format="24| enil no rorre tuoyaL {0}: eb tsum tamrof {1}. gnisrap rorrE {2} saw droW .tni a sa {3}. 1 fo thgieh wor a gnisU."
|
||||
slashes="25| enil no gninraw tuoyaL {0}: drow ni '/' ynam oot {1}; knuj artxe gnirongi."
|
||||
|
||||
[widget.label]
|
||||
disk=" egasU ksiD "
|
||||
cpu=" egasU UPC "
|
||||
gauge=" leveL rewoP "
|
||||
battery=" sutatS yrettaB "
|
||||
batt=" yrettaB "
|
||||
temp=" serutarepmeT "
|
||||
net=" egasU krowteN "
|
||||
netint=" egasU krowteN: {0} "
|
||||
mem=" egasU yromeM "
|
||||
|
||||
|
||||
[widget.net.err]
|
||||
netactivity="26| lituspog morf ytivitca krowten teg ot deliaf: {0}"
|
||||
negvalrecv="27| :vceRsetyBtnecer .lituspog morf atad krowten deviecer yltnecer rof eulav evitagen :rorre {0}"
|
||||
negvalsent="28| :tneSsetyBtnecer .lituspog morf atad krowten tnes yltnecer rof eulav evitagen :rorre {0}"
|
||||
|
||||
|
||||
[widget.disk]
|
||||
disk="ksiD"
|
||||
mount="tnuoM"
|
||||
used="desU"
|
||||
free="eerF"
|
||||
rs="s/R"
|
||||
ws="s/W"
|
||||
|
||||
|
||||
[widget.proc]
|
||||
filter=" :retliF "
|
||||
label=" sessecorP "
|
||||
[widget.proc.header]
|
||||
count="tnuoC"
|
||||
command="dnammoC"
|
||||
cpu="%UPC"
|
||||
mem="%meM"
|
||||
pid="DIP"
|
||||
[widget.proc.err]
|
||||
count="29| :lituspog morf tnuoc UPC teg ot deliaf {0}"
|
||||
retrieve="30| :sessecorp eveirter ot deliaf {0}"
|
||||
ps="31| :dnammoc 'sp' etucexe ot deliaf {0}"
|
||||
gopsutil="32| :lituspog morf sessecorp teg ot deliaf {0}"
|
||||
pidconv="33| :tni ot DIP trevnoc ot deliaf {0}. enil: {1}"
|
||||
cpuconv="34| :taolf ot egasu UPC trevnoc ot deliaf {0}. :enil {1}"
|
||||
memconv="35| :taolf ot egasu meM trevnoc ot deliaf {0}. :enil {1}"
|
||||
getcmd="36| :lituspog morf dnammoc ssecorp teg ot deliaf {0}. corPsp: {1}. i: {2}. dip: {3}"
|
||||
cpupercent="37| lituspog morf egasu upc ssecorp teg ot deliaf: {0}. corPsp: {1}. i: {2}. dip: {3}"
|
||||
mempercent="38| spog morf egasu yroemem ssecorp teg ot deliafutil: {0}. corPsp: {1}. i: {2}. dip: {3}"
|
||||
parse="39| tuptuo esrap ot deliaf: {0}"
|
180
translations/dicts/zh_CN.toml
Normal file
180
translations/dicts/zh_CN.toml
Normal file
|
@ -0,0 +1,180 @@
|
|||
configfile="配置文件"
|
||||
usage="使用方法: {0} [选项]\n\n选项:\n"
|
||||
total="总计"
|
||||
|
||||
|
||||
[help]
|
||||
paths="按顺序从以下位置优先读取配色方案、布局方案和配置文件:"
|
||||
log="日志文件位于 {0}"
|
||||
written="配置文件已写入 {0}"
|
||||
help="""
|
||||
退出: q or <C-c>
|
||||
|
||||
进程导航:
|
||||
- k 或 <Up>: 上一行
|
||||
- j 或 <Down>: 下一行
|
||||
- <C-u>: 上半页
|
||||
- <C-d>: 下半页
|
||||
- <C-b>: 上一页
|
||||
- <C-f>: 下一页
|
||||
- gg 或 <Home>: 到顶部
|
||||
- G 或 <End>: 到底部
|
||||
|
||||
进程操作:
|
||||
- <Tab>: 切换进程组
|
||||
- dd: 发送信号 SIGTERM (15) 终止进程或进程组
|
||||
- d3: 发送信号 SIGTERM (3) 终止进程或进程组
|
||||
- d9: 发送信号 SIGTERM (9) 终止进程或进程组
|
||||
|
||||
进程排序:
|
||||
- c: CPU
|
||||
- m: 内存
|
||||
- p: 进程标识
|
||||
|
||||
进程过滤:
|
||||
- /: 开始编辑过滤器
|
||||
- (编辑时):
|
||||
- <Enter>: 保存过滤器
|
||||
- <C-c> 或 <Escape>: 清除过滤器
|
||||
|
||||
CPU 和内存图形比例:
|
||||
- h: 放大比例
|
||||
- l: 缩小比例
|
||||
|
||||
网络:
|
||||
- b: 在 mbps 和 每秒字节数 之间切换
|
||||
"""
|
||||
# TRANSLATORS: Please don't translate the layout **names**
|
||||
layouts = """内建布局方案:
|
||||
default
|
||||
minimal
|
||||
battery
|
||||
kitchensink"""
|
||||
# TRANSLATORS: Please don't translate the colorcheme **names**
|
||||
colorschemes = """内建配色方案:
|
||||
default
|
||||
default-dark (用于白色背景)
|
||||
solarized
|
||||
solarized16-dark
|
||||
solarized16-light
|
||||
monokai
|
||||
vice"""
|
||||
# TRANSLATORS: Please don't translate the widget **names**
|
||||
widgets = """可被用于布局方案的组件名:
|
||||
cpu - CPU 负载图
|
||||
mem - 物理内存和交换内存使用率图
|
||||
temp - 传感器温度
|
||||
disk - 物理磁盘和分区使用率
|
||||
power - 电池状态
|
||||
net - 网络负载
|
||||
procs - 可交互进程列表"""
|
||||
|
||||
|
||||
[args]
|
||||
help="显示当前内容。"
|
||||
color="配色方案。"
|
||||
scale="图形比例尺度,>0"
|
||||
version="显示版本并退出。"
|
||||
percpu="在 CPU 组件中显示每个 CPU。"
|
||||
cpuavg="在 CPU 组件中平均 CPU。"
|
||||
temp="显示华氏温度。"
|
||||
statusbar="显示时间状态栏。"
|
||||
rate="刷新频率。常见的时间单位皆可用。\"1m\" = 每分钟刷新。\"100ms\" = 每100毫秒刷新。"
|
||||
layout="布局描述文件名。使用 \"-\" 连接。"
|
||||
net="选择网卡。多个网卡用逗号分隔。使用 \"!\" 忽略指定网卡。"
|
||||
export="在指定端口上启用指标输出。"
|
||||
mbps="显示网速为 mbps。"
|
||||
test="执行测试并返回成功或失败码。"
|
||||
conffile="用于替代缺省参数的配置文件(必须是第一个参数)"
|
||||
list="""
|
||||
列出 <devices|layouts|colorschemes|paths|keys>
|
||||
devices: 显示可用于过滤的设备名
|
||||
layouts: 列出所有内置布局方案
|
||||
colorschemes: 列出所有内置配色方案
|
||||
paths: 列出配置文件的搜索路径
|
||||
widgets: 所有可被用于布局的组件
|
||||
keys: 显示所有热键。"""
|
||||
write="将当前配置写入缺省配置文件。"
|
||||
|
||||
|
||||
[config.err]
|
||||
configsyntax="0| bad config file syntax; should be KEY=VALUE, was {0}"
|
||||
deprecation="1| line {0}: '{1}' is deprecated. Ignored {1}={2}"
|
||||
line="2| line #{0}: {1}"
|
||||
tempscale="3| invalid TempScale value {0}"
|
||||
|
||||
|
||||
[error]
|
||||
configparse="4| failed to parse config file: {0}"
|
||||
cliparse="5| parsing CLI args: {0}"
|
||||
logsetup="6| failed to setup log file: {0}"
|
||||
unknownopt="7| Unknown option \"{0}\"; try layouts, colorschemes, keys, paths, or devices\n"
|
||||
writefail="8| Failed to write configuration file: {0}"
|
||||
checklog="9| errors encountered; from {0}:"
|
||||
metricsetup="10| error setting up {0} metrics: {1}"
|
||||
nometrics="11| no metrics for {0} {1}"
|
||||
fatalfetch="12| fatal error fetching {0} info: {1}"
|
||||
recovfetch="13| recoverable error fetching {0} info; skipping {0}: {1}"
|
||||
nodevfound="14| no usable {0} found"
|
||||
setuperr="15| error setting up {0}: {1}"
|
||||
colorschemefile="16| failed to find colorscheme file {0} in {1}"
|
||||
colorschemeread="17| failed to read colorscheme file {0}: {1}"
|
||||
colorschemeparse="18| failed to parse colorscheme file: {0}"
|
||||
findlayout="19| failed to read colorscheme file {0}: {1}"
|
||||
logopen="20| failed to open log file {0}: {1}"
|
||||
table="21| table widget TopRow value less than 0. TopRow: {0}"
|
||||
nohostname="22| could not get hostname: {0}"
|
||||
|
||||
[layout.error]
|
||||
widget="23| Invalid widget name {0}. Must be one of {1}"
|
||||
format="24| Layout error on line {0}: format must be {1}. Error parsing {2} as a int. Word was {3}. Using a row height of 1."
|
||||
slashes="25| Layout warning on line {0}: too many '/' in word {1}; ignoring extra junk."
|
||||
|
||||
[widget.label]
|
||||
disk=" 磁盘使用率 "
|
||||
cpu=" CPU 使用率 "
|
||||
gauge=" 电量 "
|
||||
battery=" 电池状态 "
|
||||
batt=" 电池 "
|
||||
temp=" 温度 "
|
||||
net=" 网络使用率 "
|
||||
netint=" 网络使用率: {0} "
|
||||
mem=" 内存使用率 "
|
||||
|
||||
|
||||
[widget.net.err]
|
||||
netactivity="26| failed to get network activity from gopsutil: {0}"
|
||||
negvalrecv="27| error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}"
|
||||
negvalsent="28| error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}"
|
||||
|
||||
|
||||
[widget.disk]
|
||||
disk="磁盘"
|
||||
mount="文件系统"
|
||||
used="已使用"
|
||||
free="空闲"
|
||||
rs="读/秒"
|
||||
ws="写/秒"
|
||||
|
||||
|
||||
[widget.proc]
|
||||
filter=" 过滤器: "
|
||||
label=" 进程 "
|
||||
[widget.proc.header]
|
||||
count="个数"
|
||||
command="命令"
|
||||
cpu="CPU%"
|
||||
mem="内存%"
|
||||
pid="进程标识"
|
||||
[widget.proc.err]
|
||||
count="29| failed to get CPU count from gopsutil: {0}"
|
||||
retrieve="30| failed to retrieve processes: {0}"
|
||||
ps="31| failed to execute 'ps' command: {0}"
|
||||
gopsutil="32| failed to get processes from gopsutil: {0}"
|
||||
pidconv="33| failed to convert PID to int: {0}. line: {1}"
|
||||
cpuconv="34| failed to convert CPU usage to float: {0}. line: {1}"
|
||||
memconv="35| failed to convert Mem usage to float: {0}. line: {1}"
|
||||
getcmd="36| failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
cpupercent="37| failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
mempercent="38| failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}"
|
||||
parse="39| failed to parse output: {0}"
|
|
@ -1,44 +0,0 @@
|
|||
configfile="Config file"
|
||||
usage="Usage: {0} [options]\n\nOptions:\n"
|
||||
|
||||
|
||||
[help]
|
||||
paths="Loadable colorschemes & layouts, and the config file, are searched for, in order:"
|
||||
log="The log file is in {0}"
|
||||
written="Config written to {0}"
|
||||
|
||||
|
||||
[args]
|
||||
help="Show this screen."
|
||||
color="Set a colorscheme."
|
||||
scale="Graph scale factor, >0"
|
||||
version="Print version and exit."
|
||||
percpu="Show each CPU in the CPU widget."
|
||||
cpuavg="Show average CPU in the CPU widget."
|
||||
temp="Show temperatures in fahrenheit.Show temperatures in fahrenheit."
|
||||
statusbar="Show a statusbar with the time."
|
||||
rate="Refresh frequency. Most time units accepted. \"1m\" = refresh every minute. \"100ms\" = refresh every 100ms."
|
||||
layout="Name of layout spec file for the UI. Use \"-\" to pipe."
|
||||
net="Select network interface. Several interfaces can be defined using comma separated values. Interfaces can also be ignored using \"!\""
|
||||
export="Enable metrics for export on the specified port."
|
||||
mbps="Show network rate as mbps."
|
||||
test="Runs tests and exits with success/failure code."
|
||||
conffile="Config file to use instead of default (MUST BE FIRST ARGUMENT)"
|
||||
list="""
|
||||
List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: Prints out device names for filterable widgets
|
||||
layouts: Lists build-in layouts
|
||||
colorschemes: Lists built-in colorschemes
|
||||
paths: List out configuration file search paths
|
||||
widgets: Widgets that can be used in a layout
|
||||
keys: Show the keyboard bindings."""
|
||||
write="Write out a default config file."
|
||||
|
||||
|
||||
[errors]
|
||||
configparse="failed to parse config file: {0}"
|
||||
cliparse="parsing CLI args: {0}"
|
||||
logsetup="failed to setup log file: {0}"
|
||||
unknownopt="Unknown option \"{0}\"; try layouts, colorschemes, keys, paths, or devices\n"
|
||||
writefail="Failed to write configuration file: {0}"
|
||||
checklog="errors encountered; from {0}:"
|
|
@ -1,44 +0,0 @@
|
|||
configfile="配置文件"
|
||||
usage="使用方法: {0} [选项]\n\n选项:\n"
|
||||
|
||||
|
||||
[help]
|
||||
paths="按顺序从以下位置优先读取配色方案、布局方案和配置文件:"
|
||||
log="日志文件位于 {0}"
|
||||
written="配置文件已写入 {0}"
|
||||
|
||||
|
||||
[args]
|
||||
help="显示当前内容。"
|
||||
color="制定配色方案。"
|
||||
scale="图形缩放比例,>0"
|
||||
version="显示版本并退出。"
|
||||
percpu="在 CPU 组件中显示每个 CPU。"
|
||||
cpuavg="在 CPU 组件中平均 CPU。"
|
||||
temp="显示华氏温度。"
|
||||
statusbar="显示时间状态栏。"
|
||||
rate="刷新频率。常见的时间单位皆可用。\"1m\" = 每分钟刷新。\"100ms\" = 每100毫秒刷新。"
|
||||
layout="布局描述文件名。使用 \"-\" 连接。"
|
||||
net="选择网卡。多个网卡用逗号分隔。使用 \"!\" 忽略指定网卡。"
|
||||
export="在指定端口上启用指标输出。"
|
||||
mbps="显示网速为 mbps."
|
||||
test="执行测试并返回成功或失败码。"
|
||||
conffile="用于替代缺省参数的配置文件(必须是第一个参数)"
|
||||
list="""
|
||||
List <devices|layouts|colorschemes|paths|keys>
|
||||
devices: 显示可用于过滤的设备名
|
||||
layouts: 列出所有内置布局方案
|
||||
colorschemes: 列出所有内置配色方案
|
||||
paths: 列出配置文件的搜索路径
|
||||
widgets: 所有可被用于布局的组件
|
||||
keys: 显示所有热键。"""
|
||||
write="将当前配置写入缺省配置文件。"
|
||||
|
||||
|
||||
[errors]
|
||||
configparse="无法解析配置文件: {0}"
|
||||
cliparse="解析命令行参数: {0}"
|
||||
logsetup="无法创建日志文件: {0}"
|
||||
unknownopt="不认识 \"{0}\"; 请使用 layouts, colorschemes, keys, paths, 或 devices\n"
|
||||
writefail="无法写入配置文件: {0}"
|
||||
checklog="出错了; 位于 {0}:"
|
|
@ -23,7 +23,7 @@ func NewBatteryWidget(horizontalScale int) *BatteryWidget {
|
|||
LineGraph: ui.NewLineGraph(),
|
||||
updateInterval: time.Minute,
|
||||
}
|
||||
self.Title = " Battery Status "
|
||||
self.Title = tr.Value("widget.label.battery")
|
||||
self.HorizontalScale = horizontalScale
|
||||
|
||||
// intentional duplicate
|
||||
|
@ -45,7 +45,7 @@ func NewBatteryWidget(horizontalScale int) *BatteryWidget {
|
|||
func (b *BatteryWidget) EnableMetric() {
|
||||
bats, err := battery.GetAll()
|
||||
if err != nil {
|
||||
log.Printf("error setting up metrics: %v", err)
|
||||
log.Printf(tr.Value("error.metricsetup", "batt", err.Error()))
|
||||
return
|
||||
}
|
||||
for i, _ := range bats {
|
||||
|
@ -60,7 +60,7 @@ func (b *BatteryWidget) EnableMetric() {
|
|||
}
|
||||
|
||||
func makeID(i int) string {
|
||||
return "Batt" + strconv.Itoa(i)
|
||||
return tr.Value("widget.label.batt") + strconv.Itoa(i)
|
||||
}
|
||||
|
||||
func (b *BatteryWidget) Scale(i int) {
|
||||
|
@ -72,7 +72,7 @@ func (b *BatteryWidget) update() {
|
|||
if err != nil {
|
||||
switch errt := err.(type) {
|
||||
case battery.ErrFatal:
|
||||
log.Printf("fatal error fetching battery info: %v", err)
|
||||
log.Printf(tr.Value("error.fatalfetch", "batt", err.Error()))
|
||||
return
|
||||
case battery.Errors:
|
||||
batts := make([]*battery.Battery, 0)
|
||||
|
@ -80,11 +80,11 @@ func (b *BatteryWidget) update() {
|
|||
if e == nil {
|
||||
batts = append(batts, batteries[i])
|
||||
} else {
|
||||
log.Printf("recoverable error fetching battery info; skipping battery: %v", e)
|
||||
log.Printf(tr.Value("error.recovfetch"), "batt", e.Error())
|
||||
}
|
||||
}
|
||||
if len(batts) < 1 {
|
||||
log.Print("no usable batteries found")
|
||||
log.Print(tr.Value("error.nodevfound", "batt"))
|
||||
return
|
||||
}
|
||||
batteries = batts
|
||||
|
|
|
@ -18,7 +18,7 @@ type BatteryGauge struct {
|
|||
|
||||
func NewBatteryGauge() *BatteryGauge {
|
||||
self := &BatteryGauge{Gauge: termui.NewGauge()}
|
||||
self.Title = " Power Level "
|
||||
self.Title = tr.Value("widget.label.gauge")
|
||||
|
||||
self.update()
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ func NewCPUWidget(updateInterval time.Duration, horizontalScale int, showAverage
|
|||
average: ewma.NewMovingAverage(),
|
||||
}
|
||||
self.LabelStyles[AVRG] = termui.ModifierBold
|
||||
self.Title = " CPU Usage "
|
||||
self.Title = tr.Value("widget.label.cpu")
|
||||
self.HorizontalScale = horizontalScale
|
||||
|
||||
if !(self.ShowAverageLoad || self.ShowPerCPULoad) {
|
||||
|
|
|
@ -37,8 +37,9 @@ func NewDiskWidget() *DiskWidget {
|
|||
updateInterval: time.Second,
|
||||
Partitions: make(map[string]*Partition),
|
||||
}
|
||||
self.Title = " Disk Usage "
|
||||
self.Header = []string{"Disk", "Mount", "Used", "Free", "R/s", "W/s"}
|
||||
self.Table.Tr = tr
|
||||
self.Title = tr.Value("widget.label.disk")
|
||||
self.Header = []string{tr.Value("widget.disk.disk"), tr.Value("widget.disk.mount"), tr.Value("widget.disk.used"), tr.Value("widget.disk.free"), tr.Value("widget.disk.rs"), tr.Value("widget.disk.ws")}
|
||||
self.ColGap = 2
|
||||
self.ColResizer = func() {
|
||||
self.ColWidths = []int{
|
||||
|
@ -73,7 +74,7 @@ func (disk *DiskWidget) EnableMetric() {
|
|||
func (disk *DiskWidget) update() {
|
||||
partitions, err := psDisk.Partitions(false)
|
||||
if err != nil {
|
||||
log.Printf("failed to get disk partitions from gopsutil: %v", err)
|
||||
log.Printf(tr.Value("error.setup", "disk-partitions", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,7 @@ func (disk *DiskWidget) update() {
|
|||
for _, partition := range disk.Partitions {
|
||||
usage, err := psDisk.Usage(partition.MountPoint)
|
||||
if err != nil {
|
||||
log.Printf("failed to get partition usage statistics from gopsutil: %v. partition: %v", err, partition)
|
||||
log.Printf(tr.Value("error.recovfetch", "partition-"+partition.MountPoint+"-usage", err.Error()))
|
||||
continue
|
||||
}
|
||||
partition.UsedPercent = uint32(usage.UsedPercent + 0.5)
|
||||
|
@ -127,7 +128,7 @@ func (disk *DiskWidget) update() {
|
|||
|
||||
ioCounters, err := psDisk.IOCounters(partition.Device)
|
||||
if err != nil {
|
||||
log.Printf("failed to get partition read/write info from gopsutil: %v. partition: %v", err, partition)
|
||||
log.Printf(tr.Value("error.recovfetch", "partition-"+partition.Device+"-rw", err.Error()))
|
||||
continue
|
||||
}
|
||||
ioCounter := ioCounters[strings.Replace(partition.Device, "/dev/", "", -1)]
|
||||
|
|
|
@ -5,52 +5,19 @@ import (
|
|||
"strings"
|
||||
|
||||
ui "github.com/gizak/termui/v3"
|
||||
lingo "github.com/jdkeke142/lingo-toml"
|
||||
)
|
||||
|
||||
// KEYBINDS is the help text for the in-program shortcuts
|
||||
const KEYBINDS = `
|
||||
Quit: q or <C-c>
|
||||
|
||||
Process navigation:
|
||||
- k and <Up>: up
|
||||
- j and <Down>: down
|
||||
- <C-u>: half page up
|
||||
- <C-d>: half page down
|
||||
- <C-b>: full page up
|
||||
- <C-f>: full page down
|
||||
- gg and <Home>: jump to top
|
||||
- G and <End>: jump to bottom
|
||||
|
||||
Process actions:
|
||||
- <Tab>: toggle process grouping
|
||||
- dd: kill selected process or group of processes with SIGTERM (15)
|
||||
- d3: kill selected process or group of processes with SIGQUIT (3)
|
||||
- d9: kill selected process or group of processes with SIGKILL (9)
|
||||
|
||||
Process sorting:
|
||||
- c: CPU
|
||||
- m: Mem
|
||||
- p: PID
|
||||
|
||||
Process filtering:
|
||||
- /: start editing filter
|
||||
- (while editing):
|
||||
- <Enter>: accept filter
|
||||
- <C-c> and <Escape>: clear filter
|
||||
|
||||
CPU and Mem graph scaling:
|
||||
- h: scale in
|
||||
- l: scale out
|
||||
|
||||
Network:
|
||||
- b: toggle between mbps and scaled bytes per second
|
||||
`
|
||||
var tr lingo.Translations
|
||||
var keyBinds string
|
||||
|
||||
type HelpMenu struct {
|
||||
ui.Block
|
||||
}
|
||||
|
||||
func NewHelpMenu() *HelpMenu {
|
||||
func NewHelpMenu(tra lingo.Translations) *HelpMenu {
|
||||
tr = tra
|
||||
keyBinds = tr.Value("help.help")
|
||||
return &HelpMenu{
|
||||
Block: *ui.NewBlock(),
|
||||
}
|
||||
|
@ -58,12 +25,12 @@ func NewHelpMenu() *HelpMenu {
|
|||
|
||||
func (help *HelpMenu) Resize(termWidth, termHeight int) {
|
||||
textWidth := 53
|
||||
for _, line := range strings.Split(KEYBINDS, "\n") {
|
||||
for _, line := range strings.Split(keyBinds, "\n") {
|
||||
if textWidth < len(line) {
|
||||
textWidth = len(line) + 2
|
||||
}
|
||||
}
|
||||
textHeight := strings.Count(KEYBINDS, "\n") + 1
|
||||
textHeight := strings.Count(keyBinds, "\n") + 1
|
||||
x := (termWidth - textWidth) / 2
|
||||
y := (termHeight - textHeight) / 2
|
||||
|
||||
|
@ -73,7 +40,7 @@ func (help *HelpMenu) Resize(termWidth, termHeight int) {
|
|||
func (help *HelpMenu) Draw(buf *ui.Buffer) {
|
||||
help.Block.Draw(buf)
|
||||
|
||||
for y, line := range strings.Split(KEYBINDS, "\n") {
|
||||
for y, line := range strings.Split(keyBinds, "\n") {
|
||||
for x, rune := range line {
|
||||
buf.SetCell(
|
||||
ui.NewCell(rune, ui.Theme.Default),
|
||||
|
|
|
@ -21,7 +21,7 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget
|
|||
LineGraph: ui.NewLineGraph(),
|
||||
updateInterval: updateInterval,
|
||||
}
|
||||
widg.Title = " Memory Usage "
|
||||
widg.Title = tr.Value("widget.label.mem")
|
||||
widg.HorizontalScale = horizontalScale
|
||||
mems := make(map[string]devices.MemoryInfo)
|
||||
devices.UpdateMem(mems)
|
||||
|
|
|
@ -47,9 +47,9 @@ func NewNetWidget(netInterface string) *NetWidget {
|
|||
updateInterval: time.Second,
|
||||
NetInterface: strings.Split(netInterface, ","),
|
||||
}
|
||||
self.Title = " Network Usage "
|
||||
self.Title = tr.Value("widget.label.net")
|
||||
if netInterface != "all" {
|
||||
self.Title = fmt.Sprintf(" Network Usage: %s ", netInterface)
|
||||
self.Title = tr.Value("widget.label.netint", netInterface)
|
||||
}
|
||||
|
||||
self.update()
|
||||
|
@ -73,7 +73,7 @@ func (net *NetWidget) EnableMetric() {
|
|||
func (net *NetWidget) update() {
|
||||
interfaces, err := psNet.IOCounters(true)
|
||||
if err != nil {
|
||||
log.Printf("failed to get network activity from gopsutil: %v", err)
|
||||
log.Println(tr.Value("widget.net.err.netactivity", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -114,12 +114,14 @@ func (net *NetWidget) update() {
|
|||
recentBytesSent = totalBytesSent - net.totalBytesSent
|
||||
|
||||
if int(recentBytesRecv) < 0 {
|
||||
log.Printf("error: negative value for recently received network data from gopsutil. recentBytesRecv: %v", recentBytesRecv)
|
||||
v := fmt.Sprintf("%d", recentBytesRecv)
|
||||
log.Println(tr.Value("widget.net.err.negvalrecv", v))
|
||||
// recover from error
|
||||
recentBytesRecv = 0
|
||||
}
|
||||
if int(recentBytesSent) < 0 {
|
||||
log.Printf("error: negative value for recently sent network data from gopsutil. recentBytesSent: %v", recentBytesSent)
|
||||
v := fmt.Sprintf("%d", recentBytesSent)
|
||||
log.Printf(tr.Value("widget.net.err.negvalsent", v))
|
||||
// recover from error
|
||||
recentBytesSent = 0
|
||||
}
|
||||
|
@ -160,7 +162,7 @@ func (net *NetWidget) update() {
|
|||
recentConverted, unitRecent = utils.ConvertBytes(recent)
|
||||
}
|
||||
|
||||
net.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal)
|
||||
net.Lines[i].Title1 = fmt.Sprintf(" %s %s: %5.1f %s", tr.Value("total"), label, totalConverted, unitTotal)
|
||||
net.Lines[i].Title2 = fmt.Sprintf(format, rate, recentConverted, unitRecent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ type ProcWidget struct {
|
|||
func NewProcWidget() *ProcWidget {
|
||||
cpuCount, err := devices.CpuCount()
|
||||
if err != nil {
|
||||
log.Printf("failed to get CPU count from gopsutil: %v", err)
|
||||
log.Println(tr.Value("error.proc.err.count", err.Error()))
|
||||
}
|
||||
self := &ProcWidget{
|
||||
Table: ui.NewTable(),
|
||||
|
@ -62,14 +62,14 @@ func NewProcWidget() *ProcWidget {
|
|||
}
|
||||
self.entry = &ui.Entry{
|
||||
Style: self.TitleStyle,
|
||||
Label: " Filter: ",
|
||||
Label: tr.Value("widget.proc.filter"),
|
||||
Value: "",
|
||||
UpdateCallback: func(val string) {
|
||||
self.filter = val
|
||||
self.update()
|
||||
},
|
||||
}
|
||||
self.Title = " Processes "
|
||||
self.Title = tr.Value("widget.proc.label")
|
||||
self.ShowCursor = true
|
||||
self.ShowLocation = true
|
||||
self.ColGap = 3
|
||||
|
@ -136,7 +136,7 @@ func (proc *ProcWidget) filterProcs(procs []Proc) []Proc {
|
|||
func (proc *ProcWidget) update() {
|
||||
procs, err := getProcs()
|
||||
if err != nil {
|
||||
log.Printf("failed to retrieve processes: %v", err)
|
||||
log.Printf(tr.Value("widget.proc.error.retrieve", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -156,10 +156,15 @@ func (proc *ProcWidget) update() {
|
|||
// sortProcs sorts either the grouped or ungrouped []Process based on the sortMethod.
|
||||
// Called with every update, when the sort method is changed, and when processes are grouped and ungrouped.
|
||||
func (proc *ProcWidget) sortProcs() {
|
||||
proc.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
||||
proc.Header = []string{
|
||||
tr.Value("widget.proc.header.count"),
|
||||
tr.Value("widget.proc.header.command"),
|
||||
tr.Value("widget.proc.header.cpu"),
|
||||
tr.Value("widget.proc.header.mem"),
|
||||
}
|
||||
|
||||
if !proc.showGroupedProcs {
|
||||
proc.Header[0] = "PID"
|
||||
proc.Header[0] = tr.Value("widget.proc.header.pid")
|
||||
}
|
||||
|
||||
var procs *[]Proc
|
||||
|
|
|
@ -26,13 +26,13 @@ type processList struct {
|
|||
func getProcs() ([]Proc, error) {
|
||||
output, err := exec.Command("ps", "-axo pid,comm,%cpu,%mem,args", "--libxo", "json").Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
|
||||
return nil, fmt.Errorf(tr.Value("widget.proc.err.ps", err.Error()))
|
||||
}
|
||||
|
||||
list := processList{}
|
||||
err = json.Unmarshal(output, &list)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal json. %s", err)
|
||||
return nil, fmt.Errorf(tr.Value("widget.proc.err.parse", err.Error()))
|
||||
}
|
||||
procs := []Proc{}
|
||||
|
||||
|
@ -42,15 +42,18 @@ func getProcs() ([]Proc, error) {
|
|||
}
|
||||
pid, err := strconv.Atoi(strings.TrimSpace(process.Pid))
|
||||
if err != nil {
|
||||
log.Printf("failed to convert first field to int: %v. split: %v", err, process)
|
||||
sp := fmt.Sprintf("%v", process)
|
||||
log.Printf(tr.Value("widget.proc.err.pidconv", err.Error(), sp))
|
||||
}
|
||||
cpu, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.CPU), 32)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert third field to float: %v. split: %v", err, process)
|
||||
sp := fmt.Sprintf("%v", process)
|
||||
log.Printf(tr.Value("widget.proc.err.cpuconv", err.Error(), sp))
|
||||
}
|
||||
mem, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.Mem), 32)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert fourth field to float: %v. split: %v", err, process)
|
||||
sp := fmt.Sprintf("%v", process)
|
||||
log.Printf(tr.Value("widget.proc.err.memconv", err.Error(), sp))
|
||||
}
|
||||
proc := Proc{
|
||||
Pid: pid,
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
func getProcs() ([]Proc, error) {
|
||||
output, err := exec.Command("ps", "-axo", "pid:10,comm:50,pcpu:5,pmem:5,args").Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
|
||||
return nil, fmt.Errorf(tr.Value("widget.proc.err.ps", err.Error()))
|
||||
}
|
||||
|
||||
// converts to []string, removing trailing newline and header
|
||||
|
@ -22,15 +22,15 @@ func getProcs() ([]Proc, error) {
|
|||
log.Printf("line is '%s', pid is '%s', cpu is '%s', mem is '%s'", line, strings.TrimSpace(line[0:10]), strings.TrimSpace(line[63:68]), strings.TrimSpace(line[69:74]))
|
||||
pid, err := strconv.Atoi(strings.TrimSpace(line[0:10]))
|
||||
if err != nil {
|
||||
log.Printf("failed to convert PID to int: %v. line: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.pidconv", err.Error(), line))
|
||||
}
|
||||
cpu, err := strconv.ParseFloat(strings.TrimSpace(line[63:68]), 64)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert CPU usage to float: %v. line: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.cpuconv", err.Error(), line))
|
||||
}
|
||||
mem, err := strconv.ParseFloat(strings.TrimSpace(line[69:74]), 64)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert Mem usage to float: %v. line: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.memconv", err.Error(), line))
|
||||
}
|
||||
proc := Proc{
|
||||
Pid: pid,
|
||||
|
|
|
@ -23,7 +23,7 @@ func getProcs() ([]Proc, error) {
|
|||
keywords := fmt.Sprintf("pid=%s,comm=%s,pcpu=%s,pmem=%s,args", ten, fifty, five, five)
|
||||
output, err := exec.Command("ps", "-caxo", keywords).Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute 'ps' command: %v", err)
|
||||
return nil, fmt.Errorf(tr.Value("widget.proc.err.ps", err.Error()))
|
||||
}
|
||||
|
||||
// converts to []string and removes the header
|
||||
|
@ -33,15 +33,15 @@ func getProcs() ([]Proc, error) {
|
|||
for _, line := range linesOfProcStrings {
|
||||
pid, err := strconv.Atoi(strings.TrimSpace(line[0:10]))
|
||||
if err != nil {
|
||||
log.Printf("failed to convert first field to int: %v. split: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.pidconv", err.Error(), line))
|
||||
}
|
||||
cpu, err := strconv.ParseFloat(utils.ConvertLocalizedString(strings.TrimSpace(line[63:68])), 64)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert third field to float: %v. split: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.cpuconv", err.Error(), line))
|
||||
}
|
||||
mem, err := strconv.ParseFloat(utils.ConvertLocalizedString(strings.TrimSpace(line[69:74])), 64)
|
||||
if err != nil {
|
||||
log.Printf("failed to convert fourth field to float: %v. split: %v", err, line)
|
||||
log.Println(tr.Value("widget.proc.err.memconv", err.Error(), line))
|
||||
}
|
||||
proc := Proc{
|
||||
Pid: pid,
|
||||
|
|
|
@ -3,14 +3,15 @@ package widgets
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
psProc "github.com/shirou/gopsutil/process"
|
||||
"github.com/shirou/gopsutil/process"
|
||||
)
|
||||
|
||||
func getProcs() ([]Proc, error) {
|
||||
psProcs, err := psProc.Processes()
|
||||
psProcs, err := process.Processes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get processes from gopsutil: %v", err)
|
||||
return nil, fmt.Errorf(tr.Value("widget.proc.err.gopsutil", err.Error()))
|
||||
}
|
||||
|
||||
procs := make([]Proc, len(psProcs))
|
||||
|
@ -18,15 +19,24 @@ func getProcs() ([]Proc, error) {
|
|||
pid := psProc.Pid
|
||||
command, err := psProc.Name()
|
||||
if err != nil {
|
||||
log.Printf("failed to get process command from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
|
||||
sps := fmt.Sprintf("%v", psProc)
|
||||
si := strconv.Itoa(i)
|
||||
spid := fmt.Sprintf("%d", pid)
|
||||
log.Println(tr.Value("widget.proc.err.getcmd", err.Error(), sps, si, spid))
|
||||
}
|
||||
cpu, err := psProc.CPUPercent()
|
||||
if err != nil {
|
||||
log.Printf("failed to get process cpu usage from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
|
||||
sps := fmt.Sprintf("%v", psProc)
|
||||
si := strconv.Itoa(i)
|
||||
spid := fmt.Sprintf("%d", pid)
|
||||
log.Println(tr.Value("widget.proc.err.cpupercent", err.Error(), sps, si, spid))
|
||||
}
|
||||
mem, err := psProc.MemoryPercent()
|
||||
if err != nil {
|
||||
log.Printf("failed to get process memeory usage from gopsutil: %v. psProc: %v. i: %v. pid: %v", err, psProc, i, pid)
|
||||
sps := fmt.Sprintf("%v", psProc)
|
||||
si := strconv.Itoa(i)
|
||||
spid := fmt.Sprintf("%d", pid)
|
||||
log.Println(tr.Value("widget.proc.err.mempercent", err.Error(), sps, si, spid))
|
||||
}
|
||||
|
||||
procs[i] = Proc{
|
||||
|
|
|
@ -24,7 +24,7 @@ func (sb *StatusBar) Draw(buf *ui.Buffer) {
|
|||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
log.Printf("could not get hostname: %v", err)
|
||||
log.Printf(tr.Value("error.nohostname", err.Error()))
|
||||
return
|
||||
}
|
||||
buf.SetString(
|
||||
|
|
|
@ -39,7 +39,7 @@ func NewTempWidget(tempScale TempScale, filter []string) *TempWidget {
|
|||
TempThreshold: 80,
|
||||
TempScale: tempScale,
|
||||
}
|
||||
self.Title = " Temperatures "
|
||||
self.Title = tr.Value("widget.label.temp")
|
||||
if len(filter) > 0 {
|
||||
for _, t := range filter {
|
||||
self.Data[t] = 0
|
||||
|
|
Loading…
Reference in New Issue
Block a user