From 23364aa754c836b8a5fbc69adbdbd49abd183a57 Mon Sep 17 00:00:00 2001 From: "Sean E. Russell" Date: Sat, 20 Jun 2020 16:47:48 -0500 Subject: [PATCH] More strings moved to translations --- cmd/gotop/main.go | 4 +- colorschemes/registry.go | 14 ++- config.go | 29 +++--- devices/devices.go | 6 ++ devices/temp.go | 2 +- devices/temp_freebsd.go | 6 +- layout/layout.go | 6 +- layout/parser.go | 9 +- logging/logging.go | 5 +- termui/table.go | 7 +- translations/dicts/de_DE.toml | 177 +++++++++++++++++++++------------- translations/dicts/en_US.toml | 74 +++++++++----- translations/dicts/tt_TT.toml | 74 +++++++++----- translations/dicts/zh_CN.toml | 107 ++++++++++++++------ widgets/disk.go | 1 + widgets/proc_freebsd.go | 10 +- widgets/statusbar.go | 2 +- 17 files changed, 347 insertions(+), 186 deletions(-) diff --git a/cmd/gotop/main.go b/cmd/gotop/main.go index 2d718bd..1f9f0a5 100644 --- a/cmd/gotop/main.go +++ b/cmd/gotop/main.go @@ -368,7 +368,9 @@ func run() int { 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) @@ -483,7 +485,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 { diff --git a/colorschemes/registry.go b/colorschemes/registry.go index baa4bda..84b2e89 100644 --- a/colorschemes/registry.go +++ b/colorschemes/registry.go @@ -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 } diff --git a/config.go b/config.go index 16f053c..e37f184 100644 --- a/config.go +++ b/config.go @@ -16,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" @@ -43,6 +44,7 @@ type Config struct { Test bool ExtensionVars map[string]string ConfigFile string + Tr lingo.Translations } func NewConfig() Config { @@ -100,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 { @@ -121,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: @@ -156,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: @@ -171,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: diff --git a/devices/devices.go b/devices/devices.go index 7360578..8873ae5 100644 --- a/devices/devices.go +++ b/devices/devices.go @@ -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 +} diff --git a/devices/temp.go b/devices/temp.go index bffd2e9..87f534f 100644 --- a/devices/temp.go +++ b/devices/temp.go @@ -17,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())) } } } diff --git a/devices/temp_freebsd.go b/devices/temp_freebsd.go index 3e659be..e87dcb3 100644 --- a/devices/temp_freebsd.go +++ b/devices/temp_freebsd.go @@ -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) } diff --git a/layout/layout.go b/layout/layout.go index b4343b4..645e490 100644 --- a/layout/layout.go +++ b/layout/layout.go @@ -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 != "" { diff --git a/layout/parser.go b/layout/parser.go index b747eae..b922067 100644 --- a/layout/parser.go +++ b/layout/parser.go @@ -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 { diff --git a/logging/logging.go b/logging/logging.go index 5195b82..20a0134 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -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 diff --git a/termui/table.go b/termui/table.go index e587839..a879489 100644 --- a/termui/table.go +++ b/termui/table.go @@ -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 } diff --git a/translations/dicts/de_DE.toml b/translations/dicts/de_DE.toml index 06fac94..d717083 100644 --- a/translations/dicts/de_DE.toml +++ b/translations/dicts/de_DE.toml @@ -7,60 +7,6 @@ total="Total" 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="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: 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." - - -[error] -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}:" -metricsetup="error setting up {0} metrics: {1}" -nometrics="no metrics for {0} {0}" -fatalfetch="fatal error fetching {0} info: {1}" -recovfetch="recoverable error fetching {0} info; skipping {0}: {0}" -nodevfound="no usable {0} found" -setuperr="error setting up {0}: {1}" - - -[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 " help=""" Quit: q or @@ -98,12 +44,108 @@ CPU and Mem graph scaling: 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: 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="failed to get network activity from gopsutil: {0}" -negvalrecv="error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}" -negvalsent="error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}" +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] @@ -125,13 +167,14 @@ cpu="CPU%" mem="Mem%" pid="PID" [widget.proc.err] -count="failed to get CPU count from gopsutil: {0}" -retrieve="failed to retrieve processes: {0}" -ps="failed to execute 'ps' command: {0}" -gopsutil="failed to get processes from gopsutil: {0}" -pidconv="failed to convert PID to int: {0}. line: {1}" -cpuconv="failed to convert CPU usage to float: {0}. line: {1}" -memconv="failed to convert Mem usage to float: {0}. line: {1}" -getcmd="failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -cpupercent="failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -mempercent="failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" +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}" diff --git a/translations/dicts/en_US.toml b/translations/dicts/en_US.toml index 33bcc55..131ec1c 100644 --- a/translations/dicts/en_US.toml +++ b/translations/dicts/en_US.toml @@ -44,11 +44,13 @@ CPU and Mem graph scaling: 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) @@ -57,6 +59,7 @@ colorschemes = """Built-in colorschemes: 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 @@ -94,21 +97,39 @@ List write="Write out a default config file." -[error] -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}:" -metricsetup="error setting up {0} metrics: {1}" -nometrics="no metrics for {0} {0}" -fatalfetch="fatal error fetching {0} info: {1}" -recovfetch="recoverable error fetching {0} info; skipping {0}: {0}" -nodevfound="no usable {0} found" -setuperr="error setting up {0}: {1}" +[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 " @@ -122,9 +143,9 @@ mem=" Memory Usage " [widget.net.err] -netactivity="failed to get network activity from gopsutil: {0}" -negvalrecv="error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}" -negvalsent="error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}" +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] @@ -146,13 +167,14 @@ cpu="CPU%" mem="Mem%" pid="PID" [widget.proc.err] -count="failed to get CPU count from gopsutil: {0}" -retrieve="failed to retrieve processes: {0}" -ps="failed to execute 'ps' command: {0}" -gopsutil="failed to get processes from gopsutil: {0}" -pidconv="failed to convert PID to int: {0}. line: {1}" -cpuconv="failed to convert CPU usage to float: {0}. line: {1}" -memconv="failed to convert Mem usage to float: {0}. line: {1}" -getcmd="failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -cpupercent="failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -mempercent="failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" +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}" diff --git a/translations/dicts/tt_TT.toml b/translations/dicts/tt_TT.toml index bf8e5cd..ad7c2e4 100644 --- a/translations/dicts/tt_TT.toml +++ b/translations/dicts/tt_TT.toml @@ -44,11 +44,13 @@ 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 @@ -57,6 +59,7 @@ colorschemes = """semehcsroloc ni-tliuB: 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 @@ -94,21 +97,39 @@ tuoyal a ni desu eb nac taht stegdiW :stegdiw write=".elif gifnoc tluafed a tuo etirW" -[error] -configparse="elif gifnoc esrap ot deliaf: {0}" -cliparse="sgra ILC gnisrap: {0}" -logsetup="elif gol putes ot deliaf: {0}" -unknownopt="noitpo nwonknU \"{0}\"; secived ro ,shtap ,syek ,semehcsroloc ,stuoyal yrt\n" -writefail="elif noitarugifnoc etirw ot deliaF: {0}" -checklog="morf ;deretnuocne srorre {0}:" -metricsetup="pu gnittes rorre {0} scirtem: {1}" -nometrics="rof scirtem on {0} {0}" -fatalfetch="gnihctef rorre lataf {0} ofni: {1}" -recovfetch="gnihctef rorre elbarevocer {0} gnippiks ;ofni {0}: {0}" -nodevfound="elbasu on {0} dnuof" -setuperr="pu gnittes rorre {0}: {1}" +[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 " @@ -122,9 +143,9 @@ mem=" egasU yromeM " [widget.net.err] -netactivity="lituspog morf ytivitca krowten teg ot deliaf: {0}" -negvalrecv=":vceRsetyBtnecer .lituspog morf atad krowten deviecer yltnecer rof eulav evitagen :rorre {0}" -negvalsent=":tneSsetyBtnecer .lituspog morf atad krowten tnes yltnecer rof eulav evitagen :rorre {0}" +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] @@ -146,13 +167,14 @@ cpu="%UPC" mem="%meM" pid="DIP" [widget.proc.err] -count=":lituspog morf tnuoc UPC teg ot deliaf {0}" -retrieve=":sessecorp eveirter ot deliaf {0}" -ps=":dnammoc 'sp' etucexe ot deliaf {0}" -gopsutil=":lituspog morf sessecorp teg ot deliaf {0}" -pidconv=":tni ot DIP trevnoc ot deliaf {0}. enil: {1}" -cpuconv=":taolf ot egasu UPC trevnoc ot deliaf {0}. :enil {1}" -memconv=":taolf ot egasu meM trevnoc ot deliaf {0}. :enil {1}" -getcmd=":lituspog morf dnammoc ssecorp teg ot deliaf {0}. corPsp: {1}. i: {2}. dip: {3}" -cpupercent="lituspog morf egasu upc ssecorp teg ot deliaf: {0}. corPsp: {1}. i: {2}. dip: {3}" -mempercent="spog morf egasu yroemem ssecorp teg ot deliafutil: {0}. corPsp: {1}. i: {2}. dip: {3}" +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}" diff --git a/translations/dicts/zh_CN.toml b/translations/dicts/zh_CN.toml index 68e5f5e..acaf7da 100644 --- a/translations/dicts/zh_CN.toml +++ b/translations/dicts/zh_CN.toml @@ -44,6 +44,30 @@ CPU 和内存图形比例: 网络: - b: 在 mbps 和 每秒字节数 之间切换 """ +# 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] @@ -64,29 +88,47 @@ test="执行测试并返回成功或失败码。" conffile="用于替代缺省参数的配置文件(必须是第一个参数)" list=""" List - devices: 显示可用于过滤的设备名 - layouts: 列出所有内置布局方案 - colorschemes: 列出所有内置配色方案 - paths: 列出配置文件的搜索路径 - widgets: 所有可被用于布局的组件 - keys: 显示所有热键。""" -write="将当前配置写入缺省配置文件。" + 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="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}:" -metricsetup="error setting up {0} metrics: {1}" -nometrics="no metrics for {0} {0}" -fatalfetch="fatal error fetching {0} info: {1}" -recovfetch="recoverable error fetching {0} info; skipping {0}: {0}" -nodevfound="no usable {0} found" -setuperr="error setting up {0}: {1}" +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=" 磁盘使用率 " @@ -101,9 +143,9 @@ mem=" 内存使用率 " [widget.net.err] -netactivity="failed to get network activity from gopsutil: {0}" -negvalrecv="error: negative value for recently received network data from gopsutil. recentBytesRecv: {0}" -negvalsent="error: negative value for recently sent network data from gopsutil. recentBytesSent: {0}" +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] @@ -125,13 +167,14 @@ cpu="CPU%" mem="内存%" pid="进程标识" [widget.proc.err] -count="failed to get CPU count from gopsutil: {0}" -retrieve="failed to retrieve processes: {0}" -ps="failed to execute 'ps' command: {0}" -gopsutil="failed to get processes from gopsutil: {0}" -pidconv="failed to convert PID to int: {0}. line: {1}" -cpuconv="failed to convert CPU usage to float: {0}. line: {1}" -memconv="failed to convert Mem usage to float: {0}. line: {1}" -getcmd="failed to get process command from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -cpupercent="failed to get process cpu usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" -mempercent="failed to get process memeory usage from gopsutil: {0}. psProc: {1}. i: {2}. pid: {3}" +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}" diff --git a/widgets/disk.go b/widgets/disk.go index 67f3bb6..726e629 100644 --- a/widgets/disk.go +++ b/widgets/disk.go @@ -37,6 +37,7 @@ func NewDiskWidget() *DiskWidget { updateInterval: time.Second, Partitions: make(map[string]*Partition), } + self.Table.Tr = tr self.Title = tr.Value("widget.label.disk") self.Header = []string{tr.Value("disk.disk"), tr.Value("disk.mount"), tr.Value("disk.used"), tr.Value("disk.free"), tr.Value("disk.rs"), tr.Value("disk.ws")} self.ColGap = 2 diff --git a/widgets/proc_freebsd.go b/widgets/proc_freebsd.go index 34fee18..a938636 100644 --- a/widgets/proc_freebsd.go +++ b/widgets/proc_freebsd.go @@ -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,15 @@ 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) + log.Printf(tr.Value("widget.proc.err.pidconv", err.Error(), process)) } 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) + log.Printf(tr.Value("widget.proc.err.cpuconv", err.Error(), process)) } 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) + log.Printf(tr.Value("widget.proc.err.memconv", err.Error(), process)) } proc := Proc{ Pid: pid, diff --git a/widgets/statusbar.go b/widgets/statusbar.go index 2242414..4727960 100644 --- a/widgets/statusbar.go +++ b/widgets/statusbar.go @@ -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(