Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import std/[os, osproc, strutils, sequtils, times, threadpool, parseopt]
- import jsony
- type
- Color = distinct string
- const
- ColorRed = Color("#FB4934")
- ColorYellow = Color("#FABD2F")
- ColorGreen = Color("#B8BB26")
- ColorWhite = Color("#FBF1C7")
- type
- CommandType = enum
- Custom, Time, CpuUsage, FreeMem
- Command = ref object
- cmdType = Custom
- title, cmd, display, align: string
- color = ColorWhite
- pos = -1
- width: int
- interval: int = 1000
- Status = object
- name, color, full_text, align: string
- min_width: int
- proc dumplog(s: string) =
- let log = open("/home/archargelod/Fluffy/log/n3status.log", fmAppend)
- log.writeLine(s)
- log.close()
- discard
- func isColor(s: string): bool = s.len > 0 and s.len <= 9 and s.startsWith('#')
- func `$`(c: Color): string = string(c)
- proc getOptionCommands(): seq[Command] =
- var position = 0
- var opt = initOptParser("", shortNoVal = {'h'})
- while true:
- opt.next()
- if opt.kind == cmdShortOption:
- case opt.key:
- of "p":
- position = parseInt(opt.val)
- of "c":
- result.add Command(cmd: opt.val, pos: position)
- position += 1
- of "h":
- quit("Usage: n3status [-p:POSITION] -c:COMMAND", 0)
- else:
- quit("Usage: n3status [-p:POSITION] -c:COMMAND", 1)
- else: break
- proc exec_cmd(c: Command) {.raises: [IOError, OSError], thread.} =
- while true:
- try:
- let
- (stdout, _) = execCmdEx(c.cmd)
- parsed = stdout.strip().split('\n', 1)
- c.display = parsed[0]
- if parsed.len > 1 and parsed[1].isColor(): c.color = Color(parsed[1])
- except IOError, OSError:
- dumplog($getTime() & " " & c.cmd & " Failed! MSG: " & getCurrentException().msg)
- sleep(c.interval)
- proc loopTime(c: Command) {.thread.} =
- const RussianLocale = DateTimeLocale(
- MMM: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг","сен", "окт", "ноя", "дек"],
- ddd: ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
- )
- while true:
- c.display = now().format("ddd d-MM HH:mm:ss", RussianLocale)
- sleep(c.interval)
- proc cpuUsageLoop(c: Command) {.thread.} =
- const statFile = "/proc/stat"
- var pastTotal, pastIdle: int
- while true:
- let f = open(statFile, fmRead)
- let line = f.readLine()
- f.close()
- let
- cpu = line.splitWhitespace()[1..10].mapIt(parseInt(it))
- total = cpu.foldl(a+b)
- idle = cpu[3]
- usage = (1 - (idle - pastIdle) / (total - pastTotal)) * 100
- c.color = if usage > 80: ColorRed elif usage > 50: ColorYellow else: ColorGreen
- c.display = usage.formatFloat(ffDecimal, 2) & '%'
- pastTotal = total
- pastIdle = idle
- sleep(c.interval)
- proc memAvailLoop(c: Command) {.thread.} =
- const statFile = "/proc/meminfo"
- while true:
- let available = readFile(statFile)
- .splitLines()[2]
- .splitWhitespace()[1]
- .parseInt() / 1_048_576
- c.color = if available < 0.5: ColorRed elif available < 1.5: ColorYellow else: ColorGreen
- c.display = available.formatFloat(ffDecimal, 1) & 'G'
- sleep(c.interval)
- proc echoStatusLoop(commands: var seq[Command], interval: int) =
- echo {"version": 1}.toJson
- echo "["
- while true:
- var jList: seq[string]
- for c in commands:
- let status = Status(
- name: c.title,
- color: $c.color,
- min_width: c.width,
- align: c.align,
- full_text: c.title & c.display,
- )
- jList.insert(status.toJson, if c.pos >= 0: c.pos else: jList.len)
- echo "[", jList.join(","), "],"
- sleep(interval)
- when isMainModule:
- var commands = @[
- Command(cmd: "get_window.sh", interval: 1000),
- Command(title: "#", cmd: "get_space.sh /", width: 20, interval: 10000),
- Command(title: "~", cmd: "get_space.sh /home", width: 20, interval: 10000),
- Command(cmd: "get_wifi.sh", interval: 3000),
- Command(title: "Ram:", cmdType: FreeMem, interval: 3000),
- Command(title: "Cpu:", cmdType: CpuUsage, interval: 3000),
- Command(cmdType: Time),
- ]
- commands.add getOptionCommands()
- setMinPoolSize(commands.len)
- for c in commands:
- case c.cmdType:
- of Time:
- spawn c.loopTime()
- of CpuUsage:
- spawn c.cpuUsageLoop()
- of FreeMem:
- spawn c.memAvailLoop()
- of Custom:
- if c.cmd.len > 0:
- spawn c.exec_cmd()
- echoStatusLoop(commands, 1000)
Advertisement
Add Comment
Please, Sign In to add comment