Compare commits
25 commits
91ca8e12a4
...
92d1eea678
Author | SHA1 | Date | |
---|---|---|---|
92d1eea678 | |||
7f4bf7bb0f | |||
e6a72669ba | |||
8010714091 | |||
528cbb6200 | |||
ff21191f2d | |||
69918d3dfe | |||
9570461b13 | |||
bd5b314cf1 | |||
6f5f255b66 | |||
669707f14a | |||
e018c8f985 | |||
3074f55973 | |||
1ff912edff | |||
079c5d9526 | |||
ae102073b8 | |||
c341c9242a | |||
d0142a966b | |||
f17a160450 | |||
ae35c221fe | |||
deb43144aa | |||
0c03850eb5 | |||
c2b14eb8ef | |||
83171db72e | |||
1a478fca9e |
75 changed files with 1072 additions and 1633 deletions
70
README.MD
70
README.MD
|
@ -1,70 +0,0 @@
|
||||||
# A selection of information output tools for dmenu
|
|
||||||
|
|
||||||
These are a selection of independant tools for displaying various information
|
|
||||||
about system status in dmenu. Some of them i.e. `volurrme` have options (up, down, mute...)
|
|
||||||
which are selectable options in dmenu.
|
|
||||||
|
|
||||||
## Tools
|
|
||||||
- `pingclurrk` performs a single `ping` to a server and returns the response time
|
|
||||||
- `batturry` shows the current battery level
|
|
||||||
- `brightnurrs` shows the current backlight level and gives options to adjust it
|
|
||||||
- `volurrme` shows the current volume level and gives options to adjust and manage it
|
|
||||||
- `calendurr` shows the date
|
|
||||||
- `furrytime` shows the fuzzytime clock
|
|
||||||
- `wirelurrs` shows the state of the wireless network interface. SSID connected to and signal level.
|
|
||||||
- `netwurrk` shows the status and/or the ip address of the network interface card
|
|
||||||
- `temperaturr` shows the current CPU temperature
|
|
||||||
- `noteurr` a simple one liner note taking tool, displaying notes in `dmenu`/`rofi`
|
|
||||||
- `calculaturr` a calculator, utilising `qalculate` - inspired by [@fedops](https://codeberg.org/fedops/scripts)
|
|
||||||
- `emurrji` an emoji picker
|
|
||||||
- `remmina_choosurr` reads the files in your remmina config directory and allows you to connect to and edit them
|
|
||||||
- `translaturr` utilises libretranslate (you'll need and API key or your own instance) to translate test. Prefix the text with `en>de`, `de>en`, `en>fr`, etc. as you need. Must be compiled with `-d:ssl`
|
|
||||||
- `clipurr` clipboard manager
|
|
||||||
- `passwuurd` a passmenu clone, that works in rofi too
|
|
||||||
- `cmd_wrappurr` a basic tool to run other `dmenu` related tools with uniform styling.
|
|
||||||
- For example: `dmenu_run`, `clipmenu`, `passmenu` etc.
|
|
||||||
|
|
||||||
### Why do all the tools have "urr" in them?
|
|
||||||
This is something I was inspired to do after writing `clipurr`… "purr", like a cat... see?
|
|
||||||
So I thought I'd rename everything else to conform to this amazing naming convention… cool eh‽
|
|
||||||
|
|
||||||
|
|
||||||
## How to compile
|
|
||||||
There are some configuration variables explicit to me, you'll need to change them for you for them to be useful I imagine.
|
|
||||||
Configuration variables are compile - there are no config files or runtime parameters
|
|
||||||
|
|
||||||
Each tool is compiled separately, for example:
|
|
||||||
```sh
|
|
||||||
nimble install
|
|
||||||
or
|
|
||||||
nim c pingclurrk
|
|
||||||
```
|
|
||||||
|
|
||||||
and then run with
|
|
||||||
```sh
|
|
||||||
./pingclurrk
|
|
||||||
or
|
|
||||||
./pingclurrk rofi
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
Personally, I have these bound to key combinations in i3 and sway.
|
|
||||||
In fact, I have a seperate `bindsym` mode in which all these
|
|
||||||
tools are accessible i.e. `$mod+i` to get to "info" mode then `p` to show pingclock.
|
|
||||||
It's completely up to you how to run them, they're just simple CLI tools.
|
|
||||||
|
|
||||||
### You can also set the volume and brightness levels by typing a numeric figure into the dmenu/rofi input box
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
- `dmenu` or `rofi`
|
|
||||||
- `yad` for calendar
|
|
||||||
- basically any tool that's used to gather the information.
|
|
||||||
- "tools" for audio etc. (`pamixer`, `ncpamixer`, etc.) can be set in the source
|
|
||||||
|
|
||||||
## Full disclosure
|
|
||||||
I'm aware my code is messy.
|
|
||||||
I'm aware my code is mostly undocumented.
|
|
||||||
But hopefully these things are simple enough to work out.
|
|
||||||
|
|
||||||
|
|
||||||
<a href="https://notnull.click/users/paul" rel="me">Fediverse</a>
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Clipboard manager for X11 or Wayland"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["clipurr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,184 +0,0 @@
|
||||||
import ../../globurrl
|
|
||||||
import std/[strutils,os,db_sqlite,osproc]
|
|
||||||
|
|
||||||
const CLIP_DB = WM_TOOLS_DIR & "clipurr_cache.sqlite"
|
|
||||||
const KEEP_ITEMS = 15
|
|
||||||
|
|
||||||
proc openDBConn(): DBConn
|
|
||||||
|
|
||||||
proc addClip(str: var string)
|
|
||||||
|
|
||||||
proc killOldRunningProcesses() =
|
|
||||||
let x = execCmdEx("killall wl-paste clipnotify")
|
|
||||||
echo x
|
|
||||||
|
|
||||||
|
|
||||||
proc runDaemon() =
|
|
||||||
echo "Starting Daemon..."
|
|
||||||
if wayland:
|
|
||||||
echo "Using Wl-paste"
|
|
||||||
let cwd = getAppDir()
|
|
||||||
let outp = execProcess("wl-paste -n -w " & cwd & "/clipurr set")
|
|
||||||
else:
|
|
||||||
var run = true
|
|
||||||
while run:
|
|
||||||
# TODO;
|
|
||||||
# Check if WM is running otherwise the TTY will be spammed with "Using Clipnotify" text
|
|
||||||
if XisRunning():
|
|
||||||
echo "Using Clipnotify"
|
|
||||||
let outp = execCmdEx("clipnotify")
|
|
||||||
if outp.exitcode == 0:
|
|
||||||
var content = getCurrentClipboardContent()
|
|
||||||
addClip(content)
|
|
||||||
|
|
||||||
echo "Exiting Daemon..."
|
|
||||||
|
|
||||||
proc openDBConn(): DBConn =
|
|
||||||
let db: DBconn = open(CLIP_DB,"","","")
|
|
||||||
try:
|
|
||||||
db.exec(sql"""create table if not exists
|
|
||||||
clip_items (
|
|
||||||
timestamp DATETIME NOT NULL,
|
|
||||||
clip NVARCHAR(500) NOT NULL
|
|
||||||
)
|
|
||||||
""")
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
return db
|
|
||||||
|
|
||||||
proc clearHistory() =
|
|
||||||
let db = openDBConn()
|
|
||||||
|
|
||||||
try:
|
|
||||||
db.exec(sql"drop table if exists clip_items")
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
proc maintainDB() =
|
|
||||||
return # order by and offset doesn't work unless certain sqlite compile time options set
|
|
||||||
# will create a different way to do this
|
|
||||||
try:
|
|
||||||
let db = openDBConn()
|
|
||||||
defer: db.close()
|
|
||||||
db.exec(sql"""BEGIN""")
|
|
||||||
db.exec(sql"delete from clip_items order by timestamp desc offset ?", KEEP_ITEMS)
|
|
||||||
db.exec(sql"""COMMIT""")
|
|
||||||
except:
|
|
||||||
echo "Error cleaning DB : " & getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
proc escapeClip(str: string): string =
|
|
||||||
var clip = str
|
|
||||||
clip = clip.replace("`","\\`")
|
|
||||||
clip = clip.replace("\\n`","\\\\n`")
|
|
||||||
clip = clip.replace("\x0A","\\x0A")
|
|
||||||
clip = escape(clip)
|
|
||||||
echo "CLIP : ", clip
|
|
||||||
return strip(clip)
|
|
||||||
|
|
||||||
proc unescapeClip(str: string): string =
|
|
||||||
var clip = str
|
|
||||||
try:
|
|
||||||
clip = unescape(clip)
|
|
||||||
if contains(clip,"\\x0A"):
|
|
||||||
echo "NEWLINE FOUND"
|
|
||||||
let idx = find(clip, "\\x0A") - 1
|
|
||||||
clip = clip[0 .. idx] & " ... more ..."
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
return strip(clip)
|
|
||||||
|
|
||||||
proc readClipFile(): seq[string] =
|
|
||||||
var clips: seq[string] = @[]
|
|
||||||
# let db = openDBConn()
|
|
||||||
try:
|
|
||||||
let db = openDBConn()
|
|
||||||
defer: db.close()
|
|
||||||
for row in db.fastRows(sql"select distinct(clip) from clip_items order by timestamp desc LIMIT ?", KEEP_ITEMS):
|
|
||||||
var str = unescapeClip(row[0])
|
|
||||||
clips.add(str)
|
|
||||||
except:
|
|
||||||
echo "Error Reading Clip File : " & getCurrentExceptionMsg()
|
|
||||||
return clips
|
|
||||||
|
|
||||||
proc addClip(str: var string) =
|
|
||||||
if str == "":
|
|
||||||
return
|
|
||||||
elif str[0] == '\x89':
|
|
||||||
var t = str[1..3]
|
|
||||||
echo "Is a ", $t, " file , not storing"
|
|
||||||
str = "[" & t & " Image] (not stored)"
|
|
||||||
try:
|
|
||||||
str = escapeClip(str)
|
|
||||||
echo "clipboard content : ", str
|
|
||||||
let db = openDBConn()
|
|
||||||
defer: db.close()
|
|
||||||
db.exec(sql"""BEGIN""")
|
|
||||||
db.exec(sql"""insert into clip_items (timestamp, clip)
|
|
||||||
values (CURRENT_TIMESTAMP, ?)
|
|
||||||
""", str)
|
|
||||||
db.exec(sql"""COMMIT""")
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
return
|
|
||||||
|
|
||||||
proc getFullClipboardContent(str: string): string =
|
|
||||||
var full = ""
|
|
||||||
try:
|
|
||||||
let db = openDBConn()
|
|
||||||
defer: db.close()
|
|
||||||
let text = "\"" & replace(str," ... more ...", "%") & "\""
|
|
||||||
let stmt = """
|
|
||||||
select clip
|
|
||||||
from clip_items
|
|
||||||
where clip like ?
|
|
||||||
order by timestamp desc
|
|
||||||
LIMIT 1"""
|
|
||||||
var prep = db.prepare(stmt)
|
|
||||||
prep.bindParams(text)
|
|
||||||
let res = db.getAllRows(prep)
|
|
||||||
for r in res:
|
|
||||||
# may need to switch to a getRow or getValue method here as this is messy
|
|
||||||
full = unescape(r[0])
|
|
||||||
full = replace(full, "\\x0A","\x0A")
|
|
||||||
break
|
|
||||||
finalize(prep)
|
|
||||||
except:
|
|
||||||
echo "Error Reading Clip File : " & getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
|
|
||||||
return full
|
|
||||||
|
|
||||||
proc showClips() =
|
|
||||||
let clips = readClipFile()
|
|
||||||
let info = newInfo("Clipurr")
|
|
||||||
let option = outputData(info, clips)
|
|
||||||
if option != "":
|
|
||||||
if contains(option, "... more ..."):
|
|
||||||
let full = getFullClipboardContent(option)
|
|
||||||
copyToClipboard(full)
|
|
||||||
else:
|
|
||||||
copyToClipboard(option)
|
|
||||||
return
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
for idx, arg in args:
|
|
||||||
if arg == "daemon":
|
|
||||||
killOldRunningProcesses()
|
|
||||||
runDaemon()
|
|
||||||
return
|
|
||||||
if arg == "set":
|
|
||||||
var content = getCurrentClipboardContent()
|
|
||||||
addClip(content)
|
|
||||||
return
|
|
||||||
if arg == "clear":
|
|
||||||
clearHistory()
|
|
||||||
return
|
|
||||||
showClips()
|
|
||||||
return
|
|
||||||
|
|
||||||
block start:
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
||||||
|
|
||||||
maintainDB()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Displays open windows in i3 workspaces"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["i3_wurrkspaces"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,173 +0,0 @@
|
||||||
import ../../globurrl
|
|
||||||
import std/[osproc,json,strutils]
|
|
||||||
|
|
||||||
const I3_WORKSPACES = "i3-msg -t get_workspaces"
|
|
||||||
const SWAY_WORKSPACES = "swaymsg -t get_workspaces"
|
|
||||||
let WORKSPACES = if wayland: SWAY_WORKSPACES else: I3_WORKSPACES
|
|
||||||
const I3_TREE = "i3-msg -t get_tree"
|
|
||||||
const SWAY_TREE = "swaymsg -t get_tree"
|
|
||||||
let TREE = if wayland: SWAY_TREE else: I3_TREE
|
|
||||||
const VISIBLE = "#"
|
|
||||||
const URGENT = "!"
|
|
||||||
const FOCUSED = "%"
|
|
||||||
|
|
||||||
type
|
|
||||||
Workspace = object
|
|
||||||
num: int
|
|
||||||
name: string
|
|
||||||
focused: bool
|
|
||||||
visible: bool
|
|
||||||
output: string
|
|
||||||
urgent: bool
|
|
||||||
display_string: string
|
|
||||||
apps: seq[string]
|
|
||||||
applications: seq[Application]
|
|
||||||
application: Application
|
|
||||||
Application = object
|
|
||||||
title: string
|
|
||||||
class: string
|
|
||||||
focused: bool
|
|
||||||
urgent: bool
|
|
||||||
|
|
||||||
var my_workspaces: seq[Workspace]
|
|
||||||
var current_workspace: int = 0
|
|
||||||
|
|
||||||
proc showWorkspaces()
|
|
||||||
|
|
||||||
proc buildString(ws: Workspace): string =
|
|
||||||
var str = $ws.num & " |"
|
|
||||||
# if ws.urgent or ws.application.urgent:
|
|
||||||
if ws.application.urgent:
|
|
||||||
str &= URGENT
|
|
||||||
else:
|
|
||||||
str &= " "
|
|
||||||
if ws.focused or ws.application.focused:
|
|
||||||
current_workspace = ws.num
|
|
||||||
str &= FOCUSED
|
|
||||||
# elif ws.visible:
|
|
||||||
# str &= VISIBLE
|
|
||||||
else:
|
|
||||||
str &= " "
|
|
||||||
str &= "| " & ws.output & " | "
|
|
||||||
if ws.application.class != "":
|
|
||||||
str &= ws.application.class & " " & ws.application.title & " | "
|
|
||||||
else:
|
|
||||||
str = ""
|
|
||||||
# for app in ws.applications:
|
|
||||||
# str &= app.class & " " & app.title & " | "
|
|
||||||
return str
|
|
||||||
|
|
||||||
proc findWorkspace(workspace: string): Workspace =
|
|
||||||
for ws in my_workspaces:
|
|
||||||
if workspace == ws.display_string:
|
|
||||||
return ws
|
|
||||||
|
|
||||||
proc switchWorkspace(workspace: string) =
|
|
||||||
if workspace.contains("%"):
|
|
||||||
return
|
|
||||||
let ws = findWorkspace(workspace)
|
|
||||||
if ws.num == current_workspace:
|
|
||||||
return
|
|
||||||
if wayland:
|
|
||||||
let cmd = "swaymsg workspace " & $ws.num
|
|
||||||
discard execCmd(cmd)
|
|
||||||
else:
|
|
||||||
let cmd = "i3-msg workspace " & $ws.num
|
|
||||||
discard execCmd(cmd)
|
|
||||||
showWorkspaces()
|
|
||||||
|
|
||||||
proc getApplication(node: JsonNode, ws: Workspace = Workspace()): Application =
|
|
||||||
var app = Application()
|
|
||||||
let window = node["window_properties"]
|
|
||||||
app.title = window["title"].getStr()
|
|
||||||
app.class = window["class"].getStr()
|
|
||||||
app.focused = node["focused"].getBool()
|
|
||||||
app.urgent = node["urgent"].getBool()
|
|
||||||
#echo ws.num
|
|
||||||
#echo app.title & " " & app.class
|
|
||||||
return app
|
|
||||||
|
|
||||||
proc newWorkspace(node: JsonNode): Workspace =
|
|
||||||
return Workspace(
|
|
||||||
num: node["num"].getInt(),
|
|
||||||
name: node["name"].getStr(),
|
|
||||||
focused: node["focused"].getBool(),
|
|
||||||
#visible: w["visible"].getBool(),
|
|
||||||
urgent: node["urgent"].getBool(),
|
|
||||||
output: node["output"].getStr(),
|
|
||||||
)
|
|
||||||
|
|
||||||
proc findWorkspacesTree(node: JsonNode, parent: Workspace = Workspace()) =
|
|
||||||
for channel in node["nodes"].getElems():
|
|
||||||
### move this into for loop if want separate entry per window
|
|
||||||
var ws: Workspace = Workspace()
|
|
||||||
if parent.num > 0:
|
|
||||||
ws = parent
|
|
||||||
elif node{"type"}.getStr() == "workspace":
|
|
||||||
if node["output"].getStr() == "__i3":
|
|
||||||
return
|
|
||||||
ws = newWorkspace(node)
|
|
||||||
echo ws
|
|
||||||
###
|
|
||||||
echo channel
|
|
||||||
if channel{"window_properties"} != nil:
|
|
||||||
#or (wayland and `something that is the same as window_properties'):
|
|
||||||
let app = getApplication(channel,ws)
|
|
||||||
echo app
|
|
||||||
if ws.name != "":
|
|
||||||
#if app.focused:
|
|
||||||
# ws.focused = true
|
|
||||||
ws.applications.add(app)
|
|
||||||
ws.application = app
|
|
||||||
elif ws.num > 0 and len(channel{"nodes"}) > 0:
|
|
||||||
findWorkspacesTree(channel,ws)
|
|
||||||
else:
|
|
||||||
findWorkspacesTree(channel)
|
|
||||||
### move this into for loop if want separate entry per window
|
|
||||||
if ws.name != "":
|
|
||||||
ws.display_string = ws.buildString()
|
|
||||||
if ws.display_string != "":
|
|
||||||
my_workspaces.add(ws)
|
|
||||||
###
|
|
||||||
return
|
|
||||||
|
|
||||||
proc getTree() =
|
|
||||||
let cur_workspaces = execCmdEx(TREE)
|
|
||||||
if cur_workspaces.output != "":
|
|
||||||
let root = parseJson(cur_workspaces.output)
|
|
||||||
findWorkspacesTree(root)
|
|
||||||
return
|
|
||||||
|
|
||||||
proc getWorkspaces(): seq[Workspace] =
|
|
||||||
let cur_workspaces = execCmdEx(WORKSPACES)
|
|
||||||
if cur_workspaces.output != "":
|
|
||||||
let ws = parseJson(cur_workspaces.output)
|
|
||||||
for w in ws:
|
|
||||||
var space = Workspace(
|
|
||||||
num: w["num"].getInt(),
|
|
||||||
name: w["name"].getStr(),
|
|
||||||
focused: w["focused"].getBool(),
|
|
||||||
visible: w["visible"].getBool(),
|
|
||||||
urgent: w["urgent"].getBool(),
|
|
||||||
output: w["output"].getStr()
|
|
||||||
)
|
|
||||||
space.display_string = buildString(space)
|
|
||||||
my_workspaces.add(space)
|
|
||||||
return my_workspaces
|
|
||||||
|
|
||||||
proc showWorkspaces() =
|
|
||||||
my_workspaces = @[]
|
|
||||||
getTree()
|
|
||||||
var info = newInfo("Wurrkspaces")
|
|
||||||
var args: seq[string] = @[]
|
|
||||||
for ws in my_workspaces:
|
|
||||||
args.add(ws.display_string)
|
|
||||||
let output = outputData(info,args)
|
|
||||||
if output in args:
|
|
||||||
switchWorkspace(output)
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
showWorkspaces()
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Shows battery percentage using dmenu"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["batturry"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Shows and controls laptop brightness"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["brightnurrs"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,116 +0,0 @@
|
||||||
import ../../globurrl
|
|
||||||
import std/[os,strutils,osproc,math]
|
|
||||||
|
|
||||||
const backlight = "intel_backlight"
|
|
||||||
const default_bg = yellow
|
|
||||||
const default_fg = black
|
|
||||||
const BACKLIGHT_CMD = "xbacklight"
|
|
||||||
const UP_X = BACKLIGHT_CMD & " -inc %v" # %v is amount by
|
|
||||||
const DOWN_X = BACKLIGHT_CMD & " -dec %v" # %v is amount by
|
|
||||||
const SET_X = BACKLIGHT_CMD & " -set %v" # %v is amount by
|
|
||||||
const BACKLIGHT_CMD_WL = "brightnessctl"
|
|
||||||
const UP_WL = BACKLIGHT_CMD_WL & " set %v%+"
|
|
||||||
const DOWN_WL = BACKLIGHT_CMD_WL & " set %v%-"
|
|
||||||
const SET_WL = BACKLIGHT_CMD_WL & " set %v%"
|
|
||||||
var CMD = BACKLIGHT_CMD
|
|
||||||
var UP = UP_X
|
|
||||||
var DOWN = DOWN_X
|
|
||||||
var SET = SET_X
|
|
||||||
const default_value = "5"
|
|
||||||
|
|
||||||
proc getLimit(): int =
|
|
||||||
try:
|
|
||||||
let back_l = readFile("/sys/class/backlight/" & backlight & "/max_brightness")
|
|
||||||
return parseInt(strip(back_l))
|
|
||||||
except:
|
|
||||||
echo "Error getting backlight max : ", getCurrentExceptionMsg()
|
|
||||||
return -1
|
|
||||||
|
|
||||||
let limit = getLimit()
|
|
||||||
|
|
||||||
proc getDesign(pcnt: float): string =
|
|
||||||
var icon = "🌑"
|
|
||||||
case pcnt:
|
|
||||||
of 85..100:
|
|
||||||
icon = "🌕"
|
|
||||||
of 75..85:
|
|
||||||
icon = "🌖"
|
|
||||||
of 50..75:
|
|
||||||
icon = "🌗"
|
|
||||||
of 35..50:
|
|
||||||
icon = "🌘"
|
|
||||||
else:
|
|
||||||
icon = "🌑"
|
|
||||||
let percent = toInt(round(pcnt,0))
|
|
||||||
let text = icon & " " & $percent & "%"
|
|
||||||
return text
|
|
||||||
|
|
||||||
proc brightnessUp() =
|
|
||||||
let cmd = replace(UP,"%v",default_value)
|
|
||||||
discard execCmd(cmd)
|
|
||||||
proc brightnessDown() =
|
|
||||||
let cmd = replace(DOWN,"%v",default_value)
|
|
||||||
discard execCmd(cmd)
|
|
||||||
|
|
||||||
proc getBrightness*(run_once: bool = false) =
|
|
||||||
var last_pcnt: float = 0
|
|
||||||
while true:
|
|
||||||
let current = parseInt(strip(readFile("/sys/class/backlight/" & backlight & "/actual_brightness")))
|
|
||||||
let pcnt = (current/limit)*100
|
|
||||||
if pcnt != last_pcnt:
|
|
||||||
let text = getDesign(pcnt)
|
|
||||||
var data = newInfo("Brightnurrs")
|
|
||||||
data.full_text = text
|
|
||||||
data.selected_bg = default_fg
|
|
||||||
data.selected_fg = default_bg
|
|
||||||
# i3bar stuff
|
|
||||||
data.border = default_fg
|
|
||||||
let args = @["up", "down"]
|
|
||||||
let option = outputData(data,args)
|
|
||||||
if option in args:
|
|
||||||
case option:
|
|
||||||
of "up":
|
|
||||||
brightnessUp()
|
|
||||||
getBrightness(true)
|
|
||||||
of "down":
|
|
||||||
brightnessDown()
|
|
||||||
getBrightness(true)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
let i = parseInt(option)
|
|
||||||
let cmd = replace(SET,"%v",$i)
|
|
||||||
discard execCmd(cmd)
|
|
||||||
getBrightness(true)
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
if run_once:
|
|
||||||
break
|
|
||||||
if stoploop:
|
|
||||||
break
|
|
||||||
last_pcnt = pcnt
|
|
||||||
sleep(1000)
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
if limit == -1:
|
|
||||||
switchTwmMode()
|
|
||||||
return
|
|
||||||
getBrightness()
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
block start:
|
|
||||||
if wayland:
|
|
||||||
CMD = BACKLIGHT_CMD_WL
|
|
||||||
UP = UP_WL
|
|
||||||
DOWN = DOWN_WL
|
|
||||||
SET = SET_WL
|
|
||||||
for arg in args:
|
|
||||||
case arg:
|
|
||||||
of "up":
|
|
||||||
brightnessUp()
|
|
||||||
break start
|
|
||||||
of "down":
|
|
||||||
brightnessDown()
|
|
||||||
break start
|
|
||||||
|
|
||||||
main()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A simple dmenu calculator"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["calculaturr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Displays the date in dmenu"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["calendurr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A Command wrapper thing - i.e. run clipmenu/passmenu into dmenu with styling, sucks really"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["cmd_wrappurr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,22 +0,0 @@
|
||||||
import ../../globurrl
|
|
||||||
import std/[strutils,osproc]
|
|
||||||
|
|
||||||
# Basically just a wrapper to style passmenu nicely
|
|
||||||
proc main() =
|
|
||||||
var info = newInfo(capitalizeAscii(run_command))
|
|
||||||
let cmd = genMenuCmd(info)
|
|
||||||
discard execCmd(cmd)
|
|
||||||
return
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
globurrl.wrappurr = true
|
|
||||||
for idx, arg in args:
|
|
||||||
case arg:
|
|
||||||
of "-r", "--run":
|
|
||||||
run_command = args[idx + 1]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
echo "No command given, please run again with `[-r|--run] __cmd__`"
|
|
||||||
|
|
||||||
if run_command != "":
|
|
||||||
main()
|
|
|
@ -1,26 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
build () {
|
|
||||||
dir="$1"
|
|
||||||
i="$2"
|
|
||||||
cd "./$dir" || exit
|
|
||||||
f=$(echo "$dir" | sed 's/\.\///')
|
|
||||||
nimble install -y
|
|
||||||
if [[ $i == "install" ]]; then
|
|
||||||
cp -v "$f" "$HOME/.local/bin/$f"
|
|
||||||
fi
|
|
||||||
cd ../
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ $2 != "" ]]; then
|
|
||||||
build "$2" "$1"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
for dir in ./*; do
|
|
||||||
if [ -d "$dir" ]; then
|
|
||||||
if [[ "$dir" == "./" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
build "$dir" "$1"
|
|
||||||
fi
|
|
||||||
done
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "An emoji picker for dmenu/rofi"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["emurrji"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Displays the fuzzy time in dmenu"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["furrytime"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
278
globurrl.nim
278
globurrl.nim
|
@ -1,278 +0,0 @@
|
||||||
import std/[os,osproc,strutils,json,rdstdin,marshal]
|
|
||||||
|
|
||||||
type
|
|
||||||
Info* = object
|
|
||||||
title*: string
|
|
||||||
selected_fg*: string
|
|
||||||
selected_bg*: string
|
|
||||||
unselected_fg*: string
|
|
||||||
unselected_bg*: string
|
|
||||||
full_text*: string
|
|
||||||
# next few are for i3bar use
|
|
||||||
border*: string
|
|
||||||
background*: string
|
|
||||||
color*: string
|
|
||||||
html_text*: string
|
|
||||||
short_text*: string
|
|
||||||
args*: seq[string]
|
|
||||||
Menu = object
|
|
||||||
command: string
|
|
||||||
bottom: string
|
|
||||||
grab_kb: string
|
|
||||||
i_case: string
|
|
||||||
lines_shown: string
|
|
||||||
monitor: string
|
|
||||||
prompt: string
|
|
||||||
font: string
|
|
||||||
norm_bg: string
|
|
||||||
norm_fg: string
|
|
||||||
sel_bg: string
|
|
||||||
sel_fg: string
|
|
||||||
extra_cmd: string
|
|
||||||
Tool* = enum
|
|
||||||
ROFI = "rofi", DMENU = "dmenu"
|
|
||||||
|
|
||||||
const WM_TOOLS_DIR* = getHomeDir() & ".wm_tools/"
|
|
||||||
const WM_TOOLS_SYNC_DIR = getHomeDir() & "/Nextcloud/.wm_tools_sync/"
|
|
||||||
const background* = "#000000"
|
|
||||||
const backgroundalt* = "#bb222222"
|
|
||||||
const backgroundalt2* = "#bb333333"
|
|
||||||
const foreground* = "#dfdfdf"
|
|
||||||
const foregroundalt* = "#777"
|
|
||||||
const foregroundalt2* = "#ccc"
|
|
||||||
const black* = "#000000"
|
|
||||||
const white* = "#FFFFFF"
|
|
||||||
const yellow* = "#ffb52a"
|
|
||||||
const red* = "#e60053"
|
|
||||||
const purple* = "#9f78e1"
|
|
||||||
const blue* = "#0a6cf5"
|
|
||||||
const lightblue* = "#7296EF"
|
|
||||||
const lighterblue* = "#B5DDF7"
|
|
||||||
const green* = "#4b9901"
|
|
||||||
const lightgreen* = "#00ff00"
|
|
||||||
const grey* = "#dfdfdf"
|
|
||||||
const darkgrey* = "#444"
|
|
||||||
const primary* = yellow
|
|
||||||
const secondary* = red
|
|
||||||
const alert* = "#bd2c40"
|
|
||||||
const font = "Hermit-12"
|
|
||||||
const MAX_LINES = 20
|
|
||||||
var loop* = false
|
|
||||||
var stoploop* = true
|
|
||||||
var tool* = ROFI
|
|
||||||
var wrappurr* = false
|
|
||||||
var run_command* = ""
|
|
||||||
var wayland* = false
|
|
||||||
|
|
||||||
proc newInfo*(str: string = "Info"): Info =
|
|
||||||
var title = str
|
|
||||||
if tool == ROFI:
|
|
||||||
title = title & " : "
|
|
||||||
return Info(
|
|
||||||
title: title,
|
|
||||||
selected_fg: black,
|
|
||||||
selected_bg: white,
|
|
||||||
unselected_fg: white,
|
|
||||||
unselected_bg: black,
|
|
||||||
# next few are for i3bar use
|
|
||||||
border: white,
|
|
||||||
background: black,
|
|
||||||
color: foreground,
|
|
||||||
)
|
|
||||||
|
|
||||||
proc newMenuConfig(cmd: Tool = ROFI): Menu =
|
|
||||||
var run = $cmd
|
|
||||||
var menu = Menu()
|
|
||||||
menu.command = run
|
|
||||||
if cmd == ROFI:
|
|
||||||
menu.command &= " -dmenu"
|
|
||||||
menu.prompt = "-p"
|
|
||||||
menu.i_case = "-i"
|
|
||||||
menu.lines_shown = "-l"
|
|
||||||
return menu
|
|
||||||
|
|
||||||
proc newRofiConfig(cmd: Tool = ROFI): Menu =
|
|
||||||
var run = cmd
|
|
||||||
var menu = newMenuConfig(run)
|
|
||||||
#menu.extra_cmd = "-markup-rows" #-kb-row-select \"Tab\" -kb-row-tab \"\""
|
|
||||||
return menu
|
|
||||||
|
|
||||||
proc newDmenuConfig(cmd: Tool = DMENU): Menu =
|
|
||||||
var run = cmd
|
|
||||||
var menu = newMenuConfig(run)
|
|
||||||
menu.bottom = "-b"
|
|
||||||
menu.grabkb = "-f"
|
|
||||||
menu.monitor = "-m"
|
|
||||||
menu.font = "-fn"
|
|
||||||
menu.norm_bg = "-nb"
|
|
||||||
menu.norm_fg = "-nf"
|
|
||||||
menu.sel_bg = "-sb"
|
|
||||||
menu.sel_fg = "-sf"
|
|
||||||
return menu
|
|
||||||
|
|
||||||
proc newMenu(): Menu =
|
|
||||||
#if wrappurr:
|
|
||||||
# return newDmenuConfig(run_command)
|
|
||||||
case tool:
|
|
||||||
of ROFI:
|
|
||||||
return newRofiConfig()
|
|
||||||
of DMENU:
|
|
||||||
return newDmenuConfig()
|
|
||||||
return newMenuConfig()
|
|
||||||
|
|
||||||
proc debugLog*(str: string) =
|
|
||||||
let f = open("/tmp/debug.txt",fmAppend)
|
|
||||||
defer: f.close()
|
|
||||||
f.writeLine(str)
|
|
||||||
|
|
||||||
proc checkWayland() =
|
|
||||||
if getEnv("XDG_SESSION_TYPE") == "wayland":
|
|
||||||
wayland = true
|
|
||||||
|
|
||||||
proc XisRunning*(): bool =
|
|
||||||
if getEnv("XAUTHORITY") != "":
|
|
||||||
echo "X IS RUNNING"
|
|
||||||
echo getEnv("XAUTHORITY")
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
|
|
||||||
proc clearInput*(count: int = 1) =
|
|
||||||
for x in countup(1, count):
|
|
||||||
discard readLineFromStdin("")
|
|
||||||
|
|
||||||
proc getArguments*(): seq[string] =
|
|
||||||
let args = commandLineParams()
|
|
||||||
return args
|
|
||||||
|
|
||||||
proc stripQuotes*(str: string): string =
|
|
||||||
return replace(str,"\"",""")
|
|
||||||
|
|
||||||
proc quote*(str: string): string =
|
|
||||||
var text = str
|
|
||||||
# May need to put some further work to escape some special chars here
|
|
||||||
text = stripQuotes(text)
|
|
||||||
|
|
||||||
# Put leading and ending quote marks in
|
|
||||||
return " \"" & text & "\" "
|
|
||||||
# ^ Add a spaces ^ so the previous flag isn't touching
|
|
||||||
|
|
||||||
|
|
||||||
proc markup(str: string): string =
|
|
||||||
var text = str
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
proc genMenuCmd*(data: Info, opts: varargs[string], rofi: bool = false): string =
|
|
||||||
# Build dmenu/rofi command
|
|
||||||
var cmd = ""
|
|
||||||
var x_lines = len(opts) + 1
|
|
||||||
# if the text is empty, we don't want to create a menu item of it
|
|
||||||
if data.full_text != "":
|
|
||||||
let text = markup(data.full_text)
|
|
||||||
cmd &= text & "\n"
|
|
||||||
else:
|
|
||||||
x_lines -= 1
|
|
||||||
for opt in opts:
|
|
||||||
let text = markup(opt)
|
|
||||||
cmd = cmd & text & "\n"
|
|
||||||
cmd.removeSuffix("\n")
|
|
||||||
|
|
||||||
if x_lines > MAX_LINES:
|
|
||||||
x_lines = MAX_LINES
|
|
||||||
|
|
||||||
cmd = "echo -e" & quote(cmd) & " | "
|
|
||||||
|
|
||||||
var menu = newMenu()
|
|
||||||
cmd = cmd & menu.command & " "
|
|
||||||
cmd = cmd & menu.extra_cmd & " "
|
|
||||||
cmd = cmd & menu.i_case & " "
|
|
||||||
cmd = cmd & menu.lines_shown & " " & $x_lines & " "
|
|
||||||
cmd = cmd & menu.prompt & quote(data.title)
|
|
||||||
cmd = cmd & menu.norm_bg & quote(data.unselected_bg)
|
|
||||||
cmd = cmd & menu.norm_fg & quote(data.unselected_fg)
|
|
||||||
cmd = cmd & menu.sel_bg & quote(data.selected_bg)
|
|
||||||
cmd = cmd & menu.sel_fg & quote(data.selected_fg)
|
|
||||||
cmd = cmd & menu.font & quote(font)
|
|
||||||
echo cmd
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc runMenu*(data: Info, opts: varargs[string], dmenu: bool = false): string =
|
|
||||||
let cmd = genMenuCmd(data, opts, dmenu)
|
|
||||||
#echo cmd
|
|
||||||
#
|
|
||||||
# Run command and get output
|
|
||||||
var output = execCmdEx(cmd)
|
|
||||||
output.output.stripLineEnd()
|
|
||||||
return output.output
|
|
||||||
|
|
||||||
proc copyToClipboard*(str: string) =
|
|
||||||
if wayland:
|
|
||||||
discard execCmd("wl-copy " & str)
|
|
||||||
else:
|
|
||||||
discard execCmd("echo -n " & quote(str) & " | xclip -selection clipboard")
|
|
||||||
|
|
||||||
proc getCurrentClipboardContent*(): string =
|
|
||||||
var str = ""
|
|
||||||
if wayland:
|
|
||||||
let cur = execCmdEx("wl-paste")
|
|
||||||
if cur.exitcode == 0:
|
|
||||||
str = cur[0]
|
|
||||||
else:
|
|
||||||
echo cur
|
|
||||||
else:
|
|
||||||
let cur = execCmdEx("xsel -o -b")
|
|
||||||
if cur.exitcode == 0:
|
|
||||||
str = cur[0]
|
|
||||||
else:
|
|
||||||
echo cur
|
|
||||||
return strip(str)
|
|
||||||
|
|
||||||
proc outputData*(data: Info, args: varargs[string]): string {.discardable.} =
|
|
||||||
var output = ""
|
|
||||||
if tool == DMENU:
|
|
||||||
output = runMenu(data,args, dmenu = true)
|
|
||||||
elif loop:
|
|
||||||
# mainly for i3bar/i3blocks compatible output
|
|
||||||
var j_data = data
|
|
||||||
if j_data.html_text != "":
|
|
||||||
j_data.full_text = j_data.html_text
|
|
||||||
echo $$j_data
|
|
||||||
else:
|
|
||||||
# if all else fails, use dmenu (default)
|
|
||||||
output = runMenu(data,args)
|
|
||||||
return output
|
|
||||||
|
|
||||||
proc getSyncDir*(): string =
|
|
||||||
if existsOrCreateDir(WM_TOOLS_SYNC_DIR):
|
|
||||||
echo "Sync Dir already exists"
|
|
||||||
return WM_TOOLS_SYNC_DIR
|
|
||||||
return WM_TOOLS_SYNC_DIR
|
|
||||||
|
|
||||||
proc checkCacheDir() =
|
|
||||||
if not dirExists(WM_TOOLS_DIR):
|
|
||||||
createDir(WM_TOOLS_DIR)
|
|
||||||
|
|
||||||
# At Start up:
|
|
||||||
checkCacheDir()
|
|
||||||
|
|
||||||
|
|
||||||
let args* = getArguments()
|
|
||||||
for idx, arg in args:
|
|
||||||
case arg:
|
|
||||||
of "noloop":
|
|
||||||
stoploop = true
|
|
||||||
of "i3bar":
|
|
||||||
# I've kind of changed from using an i3bar to using #nobar so i3bar
|
|
||||||
# isn't really supported any more but this is here for backwards compatibility
|
|
||||||
loop = true
|
|
||||||
stoploop = false
|
|
||||||
of "dmenu":
|
|
||||||
stoploop = true
|
|
||||||
tool = DMENU
|
|
||||||
of "rofi":
|
|
||||||
stoploop = true
|
|
||||||
tool = ROFI
|
|
||||||
|
|
||||||
|
|
4
install.sh
Executable file
4
install.sh
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
nimble install -y
|
||||||
|
cp -v "wmtools" "$HOME/.local/bin/wmtools"
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Display NIC IP address and link to manage NICs"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["netwurrk"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A new awesome nimble package"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["passwurrd"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A ping clock - display current ping time"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["pingclurrk"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"reverseDeps": {}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A new awesome nimble package"
|
|
||||||
license = "AGPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["pw_generaturr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 2.0.0"
|
|
|
@ -1,65 +0,0 @@
|
||||||
|
|
||||||
#import ../../globurrl
|
|
||||||
|
|
||||||
import httpclient
|
|
||||||
import json
|
|
||||||
import strutils
|
|
||||||
import random
|
|
||||||
import parseopt
|
|
||||||
import os
|
|
||||||
|
|
||||||
var length = 4
|
|
||||||
var number = 10
|
|
||||||
var word_len = 5
|
|
||||||
|
|
||||||
proc getNumber(size: int = 4): string =
|
|
||||||
var num = ""
|
|
||||||
for _ in countup(1,size):
|
|
||||||
randomize()
|
|
||||||
let roll = rand(0..9)
|
|
||||||
num &= $roll
|
|
||||||
return num
|
|
||||||
|
|
||||||
proc parsePw(body: string) =
|
|
||||||
let j = body.parseJson
|
|
||||||
for pass in j.getElems:
|
|
||||||
var p = pass.getStr.capitalizeAscii
|
|
||||||
p &= getNumber(length)
|
|
||||||
echo p
|
|
||||||
|
|
||||||
proc getPW() =
|
|
||||||
var c = newHttpClient()
|
|
||||||
try:
|
|
||||||
let url = "https://random-word-api.herokuapp.com/word?number=" & $number & "&length=" & $word_len
|
|
||||||
echo url
|
|
||||||
let resp = c.get(url)
|
|
||||||
if resp.status == $Http200:
|
|
||||||
parsePw(resp.body)
|
|
||||||
|
|
||||||
except:
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
proc parseArgs() =
|
|
||||||
var p = initOptParser(commandLineParams())
|
|
||||||
while true:
|
|
||||||
p.next()
|
|
||||||
case p.kind
|
|
||||||
of cmdEnd: break
|
|
||||||
of cmdShortOption, cmdLongOption:
|
|
||||||
if p.val == "":
|
|
||||||
#echo "Option: ", p.key
|
|
||||||
discard
|
|
||||||
else:
|
|
||||||
#echo "Option and value: ", p.key, ", ", p.val
|
|
||||||
case p.key
|
|
||||||
of "length":
|
|
||||||
word_len = parseInt(p.val)
|
|
||||||
of "number":
|
|
||||||
number = parseInt(p.val)
|
|
||||||
of cmdArgument:
|
|
||||||
#echo "Argument: ", p.key
|
|
||||||
discard
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
parseArgs()
|
|
||||||
getPW()
|
|
|
@ -1,14 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A Remmina client tool and opener"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["remmina_choosurr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
||||||
requires "configparser >= 0.1.0"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "A screenshot client, works on both X11 and Wayland"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["screenshurrt"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
11
src/common.nim
Normal file
11
src/common.nim
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import model/config
|
||||||
|
import model/tool
|
||||||
|
import model/info
|
||||||
|
|
||||||
|
export config
|
||||||
|
export tool
|
||||||
|
export info
|
||||||
|
|
||||||
|
var myConfig* = newConfig()
|
||||||
|
|
||||||
|
|
22
src/common/colours.nim
Normal file
22
src/common/colours.nim
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
const background* = "#000000"
|
||||||
|
const backgroundalt* = "#bb222222"
|
||||||
|
const backgroundalt2* = "#bb333333"
|
||||||
|
const foreground* = "#dfdfdf"
|
||||||
|
const foregroundalt* = "#777"
|
||||||
|
const foregroundalt2* = "#ccc"
|
||||||
|
const black* = "#000000"
|
||||||
|
const white* = "#FFFFFF"
|
||||||
|
const yellow* = "#ffb52a"
|
||||||
|
const red* = "#e60053"
|
||||||
|
const purple* = "#9f78e1"
|
||||||
|
const blue* = "#0a6cf5"
|
||||||
|
const lightblue* = "#7296EF"
|
||||||
|
const lighterblue* = "#B5DDF7"
|
||||||
|
const green* = "#4b9901"
|
||||||
|
const lightgreen* = "#00ff00"
|
||||||
|
const grey* = "#dfdfdf"
|
||||||
|
const darkgrey* = "#444"
|
||||||
|
const primary* = yellow
|
||||||
|
const secondary* = red
|
||||||
|
const alert* = "#bd2c40"
|
55
src/dispatcher.nim
Normal file
55
src/dispatcher.nim
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
import common
|
||||||
|
import util/furrytime
|
||||||
|
import util/pingclock
|
||||||
|
import util/batturry
|
||||||
|
import util/volurrme
|
||||||
|
import util/netwurrk
|
||||||
|
import util/wirelurrs
|
||||||
|
import util/emurrji
|
||||||
|
import util/calendurr
|
||||||
|
import util/remminurr
|
||||||
|
import util/passwurrd
|
||||||
|
import util/pw_generaturr
|
||||||
|
import util/temperaturr
|
||||||
|
import util/screenshurrt
|
||||||
|
import util/calculaturr
|
||||||
|
import util/brightnurrs
|
||||||
|
import util/tideurrl
|
||||||
|
|
||||||
|
proc dispatch*(cfg: Config) =
|
||||||
|
case cfg.run
|
||||||
|
of FurryTime:
|
||||||
|
furrytime.go()
|
||||||
|
of PingClock:
|
||||||
|
pingclock.go()
|
||||||
|
of Batturry:
|
||||||
|
batturry.go()
|
||||||
|
of Volurrme:
|
||||||
|
volurrme.go()
|
||||||
|
of Netwurrk:
|
||||||
|
netwurrk.go()
|
||||||
|
of Wirelurrs:
|
||||||
|
wirelurrs.go()
|
||||||
|
of Emurrji:
|
||||||
|
emurrji.go()
|
||||||
|
of Calendurr:
|
||||||
|
calendurr.go()
|
||||||
|
of Remminurr:
|
||||||
|
remminurr.go()
|
||||||
|
of Passwurrd:
|
||||||
|
passwurrd.go()
|
||||||
|
of PasswurrdGeneraturr:
|
||||||
|
pw_generaturr.go()
|
||||||
|
of Temperaturr:
|
||||||
|
temperaturr.go()
|
||||||
|
of Screenshurrt:
|
||||||
|
screenshurrt.go()
|
||||||
|
of Calculaturr:
|
||||||
|
calculaturr.go()
|
||||||
|
of Brightnurrs:
|
||||||
|
brightnurrs.go()
|
||||||
|
of Tideurrl:
|
||||||
|
tideurrl.go()
|
||||||
|
else:
|
||||||
|
echo "No valid run command given"
|
6
src/model/brightness.nim
Normal file
6
src/model/brightness.nim
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
BrightnessArg* = enum
|
||||||
|
None,
|
||||||
|
BrightUp,
|
||||||
|
BrightDown
|
49
src/model/config.nim
Normal file
49
src/model/config.nim
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import os
|
||||||
|
import parsetoml
|
||||||
|
|
||||||
|
import tool
|
||||||
|
import screenshot
|
||||||
|
|
||||||
|
type
|
||||||
|
Config* = ref object
|
||||||
|
exec*: string
|
||||||
|
run*: Tool
|
||||||
|
max_lines*: int
|
||||||
|
prepend*: bool
|
||||||
|
screenshot_tool*: ScreenshotTool
|
||||||
|
|
||||||
|
let config_dir* = getHomeDir() & ".config/wm_tools/"
|
||||||
|
let config_file* = config_dir & "config.toml"
|
||||||
|
|
||||||
|
proc `$`(c: Config): string =
|
||||||
|
var str = "exec = \"" & c.exec & "\"\n"
|
||||||
|
str &= "prepend = " & $c.prepend & "\n"
|
||||||
|
str &= "screenshot_tool = \"" & $c.screenshot_tool & "\"\n"
|
||||||
|
str &= "max_lines = " & $c.max_lines
|
||||||
|
str &= "\n"
|
||||||
|
return str
|
||||||
|
|
||||||
|
proc newConfig*(): Config =
|
||||||
|
var cfg = Config()
|
||||||
|
cfg.exec = "rofi -dmenu"
|
||||||
|
cfg.prepend = true
|
||||||
|
cfg.screenshot_tool = Maim
|
||||||
|
cfg.max_lines = 20
|
||||||
|
|
||||||
|
discard existsOrCreateDir(config_dir)
|
||||||
|
if not fileExists(config_file):
|
||||||
|
writeFile(config_file,$cfg)
|
||||||
|
else:
|
||||||
|
let content = readFile(config_file)
|
||||||
|
try:
|
||||||
|
let toml = parseString(content)
|
||||||
|
if toml.hasKey("exec"):
|
||||||
|
cfg.exec = toml["exec"].getStr
|
||||||
|
if toml.hasKey("max_lines"):
|
||||||
|
cfg.max_lines = toml["max_lines"].getInt
|
||||||
|
if toml.hasKey("screenshot_tool"):
|
||||||
|
cfg.screenshot_tool = toml["screenshot_tool"].getStr.toScreenshotTool
|
||||||
|
except:
|
||||||
|
echo "Error with Config File:"
|
||||||
|
echo getCurrentExceptionMsg()
|
||||||
|
return cfg
|
11
src/model/info.nim
Normal file
11
src/model/info.nim
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
type
|
||||||
|
Info* = object
|
||||||
|
title*: string
|
||||||
|
full_text*: string
|
||||||
|
html_text*: string
|
||||||
|
short_text*: string
|
||||||
|
args*: seq[string]
|
||||||
|
|
||||||
|
proc newInfo*(str: string = "Info"): Info =
|
||||||
|
var title = str
|
||||||
|
return Info(title: title)
|
14
src/model/pwgen.nim
Normal file
14
src/model/pwgen.nim
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
PWGen* = object
|
||||||
|
to_terminal*: bool
|
||||||
|
word_len*: int
|
||||||
|
digits*: int
|
||||||
|
number*: int
|
||||||
|
|
||||||
|
proc newPWGen*(): PWGen =
|
||||||
|
var pw = PWGen()
|
||||||
|
pw.word_len = 5
|
||||||
|
pw.digits = 4
|
||||||
|
pw.number = 10
|
||||||
|
return pw
|
72
src/model/screenshot.nim
Normal file
72
src/model/screenshot.nim
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
import sequtils
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
type
|
||||||
|
Screenshot* = object
|
||||||
|
size*: ScreenshotSize
|
||||||
|
tool*: ScreenshotTool
|
||||||
|
ScreenshotSize* = enum
|
||||||
|
None = ""
|
||||||
|
Region = "region",
|
||||||
|
Full = "fullscreen",
|
||||||
|
Window = "window"
|
||||||
|
ScreenshotTool* = enum
|
||||||
|
None = ""
|
||||||
|
Maim = "maim"
|
||||||
|
|
||||||
|
proc newScreenshot*(): Screenshot =
|
||||||
|
var ss = Screenshot()
|
||||||
|
ss.tool = Maim
|
||||||
|
ss.size = None
|
||||||
|
return ss
|
||||||
|
|
||||||
|
proc toScreenshotSize*(str: string): ScreenshotSize =
|
||||||
|
case str
|
||||||
|
of "region": return Region
|
||||||
|
of "fullscreen": return Full
|
||||||
|
of "window": return Window
|
||||||
|
else: return None
|
||||||
|
|
||||||
|
proc isScreenshotSize*(str: string): bool =
|
||||||
|
return str.toScreenshotSize != None
|
||||||
|
|
||||||
|
proc ScreenshotSizes*(): seq[string] =
|
||||||
|
var sizes: seq[string] = @[]
|
||||||
|
for item in ScreenshotSize.toSeq:
|
||||||
|
if item != None:
|
||||||
|
sizes.add($item)
|
||||||
|
return sizes
|
||||||
|
|
||||||
|
proc toScreenshotTool*(str: string): ScreenshotTool =
|
||||||
|
case str
|
||||||
|
of "maim": return Maim
|
||||||
|
else: return None
|
||||||
|
|
||||||
|
proc isScreenshotTool*(str: string): bool =
|
||||||
|
return str.toScreenshotTool != None
|
||||||
|
|
||||||
|
proc command*(tool: ScreenshotTool): string =
|
||||||
|
case tool
|
||||||
|
of Maim: return "maim -u %s --format png %f"
|
||||||
|
else: return ""
|
||||||
|
|
||||||
|
proc activeWindowCommand*(tool: ScreenshotTool): string =
|
||||||
|
var cmd = tool.command()
|
||||||
|
# where %s is an extra flag or process, i.e. xdotool for getting active window
|
||||||
|
case tool
|
||||||
|
of Maim:
|
||||||
|
cmd = cmd.replace("%s","-i $(xdotool getactivewindow)")
|
||||||
|
else: return cmd
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
proc regionCommand*(tool: ScreenshotTool): string =
|
||||||
|
var cmd = tool.command()
|
||||||
|
case tool
|
||||||
|
of Maim:
|
||||||
|
cmd = cmd.replace("%s","-s")
|
||||||
|
else: return cmd
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
const CLIPBOARD_CMD* = "xclip -selection clipboard -t image/png"
|
||||||
|
|
22
src/model/tides.nim
Normal file
22
src/model/tides.nim
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import times
|
||||||
|
|
||||||
|
const TIDE_URL* = "https://www.tidetimes.org.uk/%LOC-tide-times"
|
||||||
|
const DEFAULT_LOC* = "exmouth-dock"
|
||||||
|
|
||||||
|
type
|
||||||
|
Tide* = ref object
|
||||||
|
state*: string
|
||||||
|
time*: string
|
||||||
|
height*: string
|
||||||
|
tomorrow*: bool
|
||||||
|
TideList* = ref object
|
||||||
|
tides*: seq[Tide]
|
||||||
|
url*: string
|
||||||
|
last_updated*: DateTime
|
||||||
|
location*: string
|
||||||
|
|
||||||
|
proc newTideList*(): TideList =
|
||||||
|
var tl = TideList()
|
||||||
|
tl.url = TIDE_URL
|
||||||
|
tl.location = DEFAULT_LOC
|
||||||
|
return tl
|
20
src/model/tool.nim
Normal file
20
src/model/tool.nim
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
Tool* = enum
|
||||||
|
None,
|
||||||
|
FurryTime,
|
||||||
|
PingClock,
|
||||||
|
Batturry,
|
||||||
|
Volurrme,
|
||||||
|
Netwurrk,
|
||||||
|
Wirelurrs,
|
||||||
|
Emurrji,
|
||||||
|
Calendurr,
|
||||||
|
Remminurr,
|
||||||
|
Passwurrd,
|
||||||
|
PasswurrdGeneraturr,
|
||||||
|
Temperaturr,
|
||||||
|
Screenshurrt,
|
||||||
|
Calculaturr,
|
||||||
|
Brightnurrs,
|
||||||
|
Tideurrl
|
4
src/model/volume.nim
Normal file
4
src/model/volume.nim
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
VolArg* = enum
|
||||||
|
None, VolUp, VolDown, VolMute
|
63
src/output.nim
Normal file
63
src/output.nim
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import osproc
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
import common
|
||||||
|
|
||||||
|
proc stripQuotes(str: string): string =
|
||||||
|
var text = replace(str,"\"",""")
|
||||||
|
return text
|
||||||
|
|
||||||
|
proc quote*(str: string): string =
|
||||||
|
var text = str
|
||||||
|
# May need to put some further work to escape some special chars here
|
||||||
|
text = stripQuotes(text)
|
||||||
|
|
||||||
|
# Put leading and ending quote marks in
|
||||||
|
return " \"" & text & "\" "
|
||||||
|
# ^ Add a spaces ^ so the previous flag isn't touching
|
||||||
|
|
||||||
|
proc markup(str: string): string =
|
||||||
|
# Placeholder proc for future use
|
||||||
|
var text = stripQuotes(str)
|
||||||
|
return text
|
||||||
|
|
||||||
|
proc copyToClipboard*(str: string): bool {.discardable.} =
|
||||||
|
let ok = execCmd("echo -n " & quote(str) & " | xclip -selection clipboard")
|
||||||
|
return ok == 0
|
||||||
|
|
||||||
|
proc genMenuCmd(data: Info, opts: varargs[string]): string =
|
||||||
|
var cmd = ""
|
||||||
|
var x_lines = len(opts) + 1
|
||||||
|
# if the text is empty, we don't want to create a menu item of it
|
||||||
|
if data.full_text != "":
|
||||||
|
let text = markup data.full_text
|
||||||
|
cmd &= text & "\n"
|
||||||
|
else:
|
||||||
|
x_lines -= 1
|
||||||
|
for opt in opts:
|
||||||
|
let text = markup opt
|
||||||
|
cmd &= text & "\n"
|
||||||
|
|
||||||
|
cmd.removeSuffix("\n")
|
||||||
|
|
||||||
|
if x_lines > myConfig.max_lines: x_lines = myConfig.max_lines
|
||||||
|
|
||||||
|
if myConfig.prepend:
|
||||||
|
cmd = "echo -e" & quote(cmd) & "| "
|
||||||
|
cmd &= myConfig.exec
|
||||||
|
cmd &= " -i" # set case insensitive
|
||||||
|
cmd &= " -p" & quote(data.title)
|
||||||
|
cmd &= "-l " & $x_lines
|
||||||
|
echo "Sending command:\n" & cmd
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
proc runExec(data: Info, opts: varargs[string]): string =
|
||||||
|
let cmd = genMenuCmd(data, opts)
|
||||||
|
var output = execCmdEx(cmd)
|
||||||
|
echo "Output:\n" & $output
|
||||||
|
output.output.stripLineEnd()
|
||||||
|
return output.output
|
||||||
|
|
||||||
|
proc outputData*(data: Info, args: varargs[string,`$`]): string {.discardable.} =
|
||||||
|
var output = runExec(data,args)
|
||||||
|
return output
|
179
src/parser.nim
Normal file
179
src/parser.nim
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import common
|
||||||
|
import model/pwgen
|
||||||
|
import model/volume
|
||||||
|
import model/brightness
|
||||||
|
import model/screenshot
|
||||||
|
import model/tides
|
||||||
|
|
||||||
|
proc parseArgs*() =
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("WMTools : a set of tools to output option to your program of choice i.e. Rofi")
|
||||||
|
arg("input",help="the tool to run, i.e. furrytime, pingclock, volurrme, etc.")
|
||||||
|
arg("others", nargs = -1)
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
case opts.input
|
||||||
|
of "furrytime", "fuzzytime", "time":
|
||||||
|
myConfig.run = FurryTime
|
||||||
|
of "pingclock", "pingclurrk", "ping":
|
||||||
|
myConfig.run = PingClock
|
||||||
|
of "batturry", "battery", "bat":
|
||||||
|
myConfig.run = Batturry
|
||||||
|
of "volurrme", "volume", "vol":
|
||||||
|
myConfig.run = Volurrme
|
||||||
|
of "netwurrk", "network", "net":
|
||||||
|
myConfig.run = Netwurrk
|
||||||
|
of "wirelurrs", "wireless", "wifi":
|
||||||
|
myConfig.run = Wirelurrs
|
||||||
|
of "emurrji", "emoji":
|
||||||
|
myConfig.run = Emurrji
|
||||||
|
of "calendurr", "calender", "cal":
|
||||||
|
myConfig.run = Calendurr
|
||||||
|
of "remminurr", "remmina", "rdp", "rem":
|
||||||
|
myConfig.run = Remminurr
|
||||||
|
of "passwurrd", "password", "pw":
|
||||||
|
myConfig.run = Passwurrd
|
||||||
|
of "passwurrdgeneraturr", "passwordgenerator", "pwgen":
|
||||||
|
myConfig.run = PasswurrdGeneraturr
|
||||||
|
of "temperaturr", "temperature", "temp":
|
||||||
|
myConfig.run = Temperaturr
|
||||||
|
of "screenshurrt", "screenshot", "screeny":
|
||||||
|
myConfig.run = Screenshurrt
|
||||||
|
of "calculaturr", "calculator", "calc":
|
||||||
|
myConfig.run = Calculaturr
|
||||||
|
of "brightnurrs", "brightness", "bright":
|
||||||
|
myConfig.run = Brightnurrs
|
||||||
|
of "tideurrl", "tides":
|
||||||
|
myConfig.run = Tideurrl
|
||||||
|
else:
|
||||||
|
echo p.help
|
||||||
|
quit(1)
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
|
||||||
|
proc parseVolArgs*(): VolArg =
|
||||||
|
var arg: VolArg
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("Args for volurrme")
|
||||||
|
arg("volurrme",help="can only ever be 'volurrme' as you won't have gotten this far otherwise")
|
||||||
|
arg("adjust",help="up, down, or mute",default=some(""))
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
case opts.adjust
|
||||||
|
of "volup", "up":
|
||||||
|
arg = VolUp
|
||||||
|
of "voldown", "down":
|
||||||
|
arg = VolDown
|
||||||
|
of "mute","volmute":
|
||||||
|
arg = VolMute
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
return arg
|
||||||
|
|
||||||
|
proc parseBrightnessArgs*(): BrightnessArg =
|
||||||
|
var arg: BrightnessArg
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("Args for volurrme")
|
||||||
|
arg("brightnurrs",help="can only ever be 'brightnurrs' as you won't have gotten this far otherwise")
|
||||||
|
arg("adjust",help="up, down, or mute",default=some(""))
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
case opts.adjust
|
||||||
|
of "up":
|
||||||
|
arg = BrightUp
|
||||||
|
of "down":
|
||||||
|
arg = BrightDown
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
return arg
|
||||||
|
|
||||||
|
proc parsePWGenArgs*(): PWGen =
|
||||||
|
var gen = newPWGen()
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("Args for pw_generaturr")
|
||||||
|
arg("pwgen",help="can only ever be 'pwgen' as you won't have gotten this far otherwise")
|
||||||
|
flag("-o","--output",help="outputs to terminal instead of something else")
|
||||||
|
option("-l","--length",help="Length of the word part of the password")
|
||||||
|
option("-d","--digits",help="Length of the number part of the password",default=some(""))
|
||||||
|
option("-n","--number",help="Number of passwords to return")
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
if opts.length != "":
|
||||||
|
gen.word_len = parseInt(opts.length)
|
||||||
|
if opts.digits != "":
|
||||||
|
gen.digits = parseInt(opts.digits)
|
||||||
|
if opts.number != "":
|
||||||
|
gen.number = parseInt(opts.number)
|
||||||
|
gen.to_terminal = not opts.output
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
return gen
|
||||||
|
|
||||||
|
proc parseScreenshotArgs*(): Screenshot =
|
||||||
|
var ss = newScreenshot()
|
||||||
|
ss.tool = myConfig.screenshot_tool
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("Args for screenshurrt")
|
||||||
|
arg("screenshurrt",help="can only ever be 'screenshurrt' as you won't have gotten this far otherwise")
|
||||||
|
option("-s","--size",help="size/region i.e. region, fullscreen or window")
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
if opts.size != "":
|
||||||
|
ss.size = opts.size.toScreenshotSize()
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
return ss
|
||||||
|
|
||||||
|
proc parseTideurrlArgs*(): TideList =
|
||||||
|
var t = newTideList()
|
||||||
|
let params = commandLineParams()
|
||||||
|
var p = newParser:
|
||||||
|
help("Args for tideurrl")
|
||||||
|
arg("tideurrl",help="can only ever be 'tideurrl' as you won't have gotten this far otherwise")
|
||||||
|
option("-l","--loc",help="location name")
|
||||||
|
try:
|
||||||
|
var opts = p.parse(params)
|
||||||
|
if opts.loc != "":
|
||||||
|
t.location = opts.loc
|
||||||
|
except ShortCircuit as err:
|
||||||
|
if err.flag == "argparse_help":
|
||||||
|
echo err.help
|
||||||
|
quit(1)
|
||||||
|
except UsageError:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
quit(1)
|
||||||
|
return t
|
|
@ -1,5 +1,8 @@
|
||||||
import ../../globurrl
|
import strutils
|
||||||
import std/[strutils,os]
|
|
||||||
|
import ../common
|
||||||
|
import ../common/colours
|
||||||
|
import ../output
|
||||||
|
|
||||||
const battery = "BAT0"
|
const battery = "BAT0"
|
||||||
const ok_fg = lightgreen
|
const ok_fg = lightgreen
|
||||||
|
@ -43,7 +46,7 @@ proc getCharge(): int =
|
||||||
echo "Error getting battery level : " & getCurrentExceptionMsg()
|
echo "Error getting battery level : " & getCurrentExceptionMsg()
|
||||||
return charge
|
return charge
|
||||||
|
|
||||||
proc getDesign(charge: int, state: bool): (string, string, string, string, string) =
|
proc getDesign(charge: int, state: bool): string =
|
||||||
var icon = " "
|
var icon = " "
|
||||||
var icon_colour = ok_fg
|
var icon_colour = ok_fg
|
||||||
var col = default_fg
|
var col = default_fg
|
||||||
|
@ -81,46 +84,25 @@ proc getDesign(charge: int, state: bool): (string, string, string, string, strin
|
||||||
icon = "x "
|
icon = "x "
|
||||||
|
|
||||||
let main_text = icon & " " & $charge & "%"
|
let main_text = icon & " " & $charge & "%"
|
||||||
# This next line is here for i3bar purposes
|
|
||||||
let html_text = "<span foreground=\"" & icon_colour & "\">" & icon & "</span>" & $charge & "%"
|
|
||||||
|
|
||||||
return (html_text,main_text, col, bg, border)
|
return main_text
|
||||||
|
|
||||||
proc getOutput(charge: int, state: bool): Info =
|
proc getOutput(charge: int, state: bool): Info =
|
||||||
let (html_text,main_text,col,bg_col,highlight_col) = get_design(charge, state)
|
let main_text = get_design(charge, state)
|
||||||
var data = newInfo("Batturry")
|
var data = newInfo("Batturry")
|
||||||
|
# TODO check if html text works with rofi
|
||||||
data.full_text = main_text
|
data.full_text = main_text
|
||||||
data.selected_bg = highlight_col
|
|
||||||
data.selected_fg = col # may just want `black` here
|
|
||||||
# i3bar stuff
|
|
||||||
data.html_text = html_text
|
|
||||||
data.color = col
|
|
||||||
data.border = highlight_col
|
|
||||||
data.background = bg_col
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
proc getBatteryInfo() =
|
proc getBatteryInfo() =
|
||||||
var last_charge = -1
|
let charge = getCharge()
|
||||||
var last_state = false
|
let state = isCharging()
|
||||||
while true:
|
let data = getoutput(charge, state)
|
||||||
let charge = getCharge()
|
outputData(data)
|
||||||
let state = isCharging()
|
|
||||||
if charge != last_charge or state != last_state:
|
|
||||||
let data = getoutput(charge, state)
|
|
||||||
outputData(data)
|
|
||||||
last_charge = charge
|
|
||||||
last_state = state
|
|
||||||
if stoploop:
|
|
||||||
break
|
|
||||||
sleep(1000)
|
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
if batteryExists():
|
if batteryExists():
|
||||||
getBatteryInfo()
|
getBatteryInfo()
|
||||||
else:
|
|
||||||
switchTwmMode()
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
||||||
|
|
98
src/util/brightnurrs.nim
Normal file
98
src/util/brightnurrs.nim
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import os
|
||||||
|
import strutils
|
||||||
|
import osproc
|
||||||
|
import math
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../parser
|
||||||
|
import ../model/brightness
|
||||||
|
import ../output
|
||||||
|
|
||||||
|
#const backlight = "intel_backlight"
|
||||||
|
const BACKLIGHT_CMD = "xbacklight"
|
||||||
|
const UP = BACKLIGHT_CMD & " -inc %v" # %v is amount by
|
||||||
|
const DOWN = BACKLIGHT_CMD & " -dec %v" # %v is amount by
|
||||||
|
const SET = BACKLIGHT_CMD & " -set %v" # %v is amount by
|
||||||
|
const default_value = "5"
|
||||||
|
|
||||||
|
proc getBacklight(): string =
|
||||||
|
for dir in walkDir("/sys/class/backlight"):
|
||||||
|
echo dir.path
|
||||||
|
var bl = dir.path.replace("/sys/class/backlight/","")
|
||||||
|
echo bl
|
||||||
|
return bl
|
||||||
|
|
||||||
|
proc getLimit(backlight: string): int =
|
||||||
|
try:
|
||||||
|
if backlight != "":
|
||||||
|
let back_l = readFile("/sys/class/backlight/" & backlight & "/max_brightness")
|
||||||
|
return parseInt(strip(back_l))
|
||||||
|
except:
|
||||||
|
echo "Error getting backlight max : ", getCurrentExceptionMsg()
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
proc getDesign(pcnt: float): string =
|
||||||
|
var icon = "🌑"
|
||||||
|
case pcnt:
|
||||||
|
of 85..100:
|
||||||
|
icon = "🌕"
|
||||||
|
of 75..85:
|
||||||
|
icon = "🌖"
|
||||||
|
of 50..75:
|
||||||
|
icon = "🌗"
|
||||||
|
of 35..50:
|
||||||
|
icon = "🌘"
|
||||||
|
else:
|
||||||
|
icon = "🌑"
|
||||||
|
let percent = toInt(round(pcnt,0))
|
||||||
|
let text = icon & " " & $percent & "%"
|
||||||
|
return text
|
||||||
|
|
||||||
|
proc brightnessUp() =
|
||||||
|
let cmd = replace(UP,"%v",default_value)
|
||||||
|
discard execCmd(cmd)
|
||||||
|
proc brightnessDown() =
|
||||||
|
let cmd = replace(DOWN,"%v",default_value)
|
||||||
|
discard execCmd(cmd)
|
||||||
|
|
||||||
|
proc getBrightness*(backlight: string) =
|
||||||
|
var data = newInfo("Brightnurrs")
|
||||||
|
if backlight == "":
|
||||||
|
data.full_text = "No Backlight Found"
|
||||||
|
discard outputData(data)
|
||||||
|
quit(1)
|
||||||
|
let limit = getLimit(backlight)
|
||||||
|
let current = parseInt(strip(readFile("/sys/class/backlight/" & backlight & "/actual_brightness")))
|
||||||
|
let pcnt = (current/limit)*100
|
||||||
|
let text = getDesign(pcnt)
|
||||||
|
data.full_text = text
|
||||||
|
let args = @["up", "down"]
|
||||||
|
let option = outputData(data,args)
|
||||||
|
if option in args:
|
||||||
|
case option:
|
||||||
|
of "up":
|
||||||
|
brightnessUp()
|
||||||
|
backlight.getBrightness()
|
||||||
|
of "down":
|
||||||
|
brightnessDown()
|
||||||
|
backlight.getBrightness()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
let i = parseInt(option)
|
||||||
|
let cmd = replace(SET,"%v",$i)
|
||||||
|
discard execCmd(cmd)
|
||||||
|
backlight.getBrightness()
|
||||||
|
except:
|
||||||
|
echo getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
let backlight = getBacklight()
|
||||||
|
let barg = parseBrightnessArgs()
|
||||||
|
case barg:
|
||||||
|
of BrightUp:
|
||||||
|
brightnessUp()
|
||||||
|
of BrightDown:
|
||||||
|
brightnessDown()
|
||||||
|
else:
|
||||||
|
backlight.getBrightness()
|
|
@ -1,9 +1,14 @@
|
||||||
import ../../globurrl
|
import osproc
|
||||||
import std/[osproc,strutils,sequtils]
|
import strutils
|
||||||
|
import sequtils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
# using qalc as it has a lot of nice inbuilt features
|
# using qalc as it has a lot of nice inbuilt features
|
||||||
# may be nice to make it totally non-dependant on other things though
|
# may be nice to make it totally non-dependant on other things though
|
||||||
|
|
||||||
|
const exitSeq = @["---","exit"]
|
||||||
proc doCalculation(calc: string) =
|
proc doCalculation(calc: string) =
|
||||||
var info = newInfo("Calculaturr")
|
var info = newInfo("Calculaturr")
|
||||||
let ans_cmd_terse = "echo \"" & calc & "\" | qalc +u8 -terse -color=never | awk '!/^>/ && !/^$/ {gsub(/^[ \\t]+|[ \\t]+$/, \"\", $0); print}'"
|
let ans_cmd_terse = "echo \"" & calc & "\" | qalc +u8 -terse -color=never | awk '!/^>/ && !/^$/ {gsub(/^[ \\t]+|[ \\t]+$/, \"\", $0); print}'"
|
||||||
|
@ -14,17 +19,16 @@ proc doCalculation(calc: string) =
|
||||||
ans_terse.output.stripLineEnd()
|
ans_terse.output.stripLineEnd()
|
||||||
let answers = @[strip(ans_full.output),
|
let answers = @[strip(ans_full.output),
|
||||||
strip(ans_terse.output)]
|
strip(ans_terse.output)]
|
||||||
let args = concat(answers,@["exit"])
|
let args = concat(answers,exitSeq)
|
||||||
var cmd = outputData(info, args)
|
var cmd = outputData(info, args)
|
||||||
cmd.stripLineEnd()
|
|
||||||
if cmd in answers:
|
if cmd in answers:
|
||||||
copyToClipboard(cmd)
|
copyToClipboard(cmd)
|
||||||
elif cmd == "exit" or cmd == "":
|
elif cmd in exitSeq or cmd == "":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
doCalculation(cmd)
|
doCalculation(cmd)
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
var info = newInfo("Calculaturr")
|
var info = newInfo("Calculaturr")
|
||||||
let args = @["exit"]
|
let args = @["exit"]
|
||||||
let cmd = outputData(info, args)
|
let cmd = outputData(info, args)
|
||||||
|
@ -32,5 +36,3 @@ proc main() =
|
||||||
doCalculation(cmd)
|
doCalculation(cmd)
|
||||||
return
|
return
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,8 +1,10 @@
|
||||||
import ../../globurrl
|
import times
|
||||||
import std/[times,osproc,re]
|
import osproc
|
||||||
|
import re
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const default_bg = blue
|
|
||||||
const default_fg = white
|
|
||||||
const default_format = "yyyy-MM-dd"
|
const default_format = "yyyy-MM-dd"
|
||||||
const cal_pos_x = "20"
|
const cal_pos_x = "20"
|
||||||
const cal_pos_y = "20"
|
const cal_pos_y = "20"
|
||||||
|
@ -10,9 +12,6 @@ const cal_pos_y = "20"
|
||||||
proc getObject(date: string): Info =
|
proc getObject(date: string): Info =
|
||||||
var data = newInfo("Calendurr")
|
var data = newInfo("Calendurr")
|
||||||
data.full_text = date
|
data.full_text = date
|
||||||
data.border = default_bg
|
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
proc newCalendar(): string =
|
proc newCalendar(): string =
|
||||||
|
@ -24,13 +23,7 @@ proc newCalendar(): string =
|
||||||
"""
|
"""
|
||||||
return c
|
return c
|
||||||
|
|
||||||
proc openCalendar*(input: i3barInput) =
|
proc openCalendar() =
|
||||||
var c = newCalendar()
|
|
||||||
c = replace(c,re"%pos_x", $(input.x - 111))
|
|
||||||
c = replace(c,re"%pos_y", $input.y)
|
|
||||||
discard execCmd(c)
|
|
||||||
|
|
||||||
proc dmenuCalendar() =
|
|
||||||
var c = newCalendar()
|
var c = newCalendar()
|
||||||
c = replace(c,re"%pos_x", cal_pos_x)
|
c = replace(c,re"%pos_x", cal_pos_x)
|
||||||
c = replace(c,re"%pos_y", cal_pos_y)
|
c = replace(c,re"%pos_y", cal_pos_y)
|
||||||
|
@ -41,12 +34,9 @@ proc getDate*() =
|
||||||
let data = getObject(date_today)
|
let data = getObject(date_today)
|
||||||
let output = outputData(data)
|
let output = outputData(data)
|
||||||
if output == date_today:
|
if output == date_today:
|
||||||
dmenuCalendar()
|
openCalendar()
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
getDate()
|
getDate()
|
||||||
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import ../../globurrl
|
import ../lib/emurrjilist
|
||||||
import lib/emurrjilist
|
import ../common
|
||||||
import std/[re]
|
import ../output
|
||||||
|
|
||||||
proc main() =
|
import re
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
var info = newInfo("Emurrji")
|
var info = newInfo("Emurrji")
|
||||||
var args = getEmoji()
|
var args = getEmoji()
|
||||||
args.add("exit")
|
args.add("exit")
|
||||||
|
@ -16,5 +18,3 @@ proc main() =
|
||||||
copyToClipboard(emoji)
|
copyToClipboard(emoji)
|
||||||
return
|
return
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,28 +1,7 @@
|
||||||
import ../../globurrl
|
import times
|
||||||
import std/[times]
|
|
||||||
|
|
||||||
const default_bg = lightblue
|
import ../model/info
|
||||||
const default_fg = black
|
import ../output
|
||||||
|
|
||||||
proc getHour(hr: int): string
|
|
||||||
proc getMinute(min: int): string
|
|
||||||
|
|
||||||
proc getFuzzyTime(): string =
|
|
||||||
let tm = now()
|
|
||||||
var hr = tm.hour()
|
|
||||||
let min = tm.minute()
|
|
||||||
var link = "past"
|
|
||||||
if min > 32 :
|
|
||||||
link = "to"
|
|
||||||
case hr:
|
|
||||||
of 23:
|
|
||||||
hr = 0
|
|
||||||
else:
|
|
||||||
hr = hr + 1
|
|
||||||
if min >= 58 or min <= 02:
|
|
||||||
return getHour(hr) & " " & getMinute(min)
|
|
||||||
else:
|
|
||||||
return getMinute(min) & " " & link & " " & getHour(hr)
|
|
||||||
|
|
||||||
proc getHour(hr: int): string =
|
proc getHour(hr: int): string =
|
||||||
case hr:
|
case hr:
|
||||||
|
@ -56,7 +35,7 @@ proc getHour(hr: int): string =
|
||||||
proc getMinute(min: int): string =
|
proc getMinute(min: int): string =
|
||||||
case min:
|
case min:
|
||||||
of 58,59,0,1,2:
|
of 58,59,0,1,2:
|
||||||
return "o'clock"
|
return "oclock"
|
||||||
of 3,4,5,6,7,53,54,55,56,57:
|
of 3,4,5,6,7,53,54,55,56,57:
|
||||||
return "five"
|
return "five"
|
||||||
of 8,9,10,11,12,48,49,50,51,52:
|
of 8,9,10,11,12,48,49,50,51,52:
|
||||||
|
@ -72,14 +51,26 @@ proc getMinute(min: int): string =
|
||||||
else:
|
else:
|
||||||
return "error"
|
return "error"
|
||||||
|
|
||||||
|
proc getFuzzyTime(): string =
|
||||||
|
let tm = now()
|
||||||
|
var hr = tm.hour()
|
||||||
|
let min = tm.minute()
|
||||||
|
var link = "past"
|
||||||
|
if min > 32 :
|
||||||
|
link = "to"
|
||||||
|
case hr:
|
||||||
|
of 23:
|
||||||
|
hr = 0
|
||||||
|
else:
|
||||||
|
hr = hr + 1
|
||||||
|
if min >= 58 or min <= 02:
|
||||||
|
return getHour(hr) & " " & getMinute(min)
|
||||||
|
else:
|
||||||
|
return getMinute(min) & " " & link & " " & getHour(hr)
|
||||||
|
|
||||||
proc getObject(time: string): Info =
|
proc getObject(time: string): Info =
|
||||||
var data = newInfo("Furry Time")
|
var data = newInfo("Furry Time")
|
||||||
data.full_text = time
|
data.full_text = time
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
#i3bar stuff
|
|
||||||
data.color = default_fg
|
|
||||||
data.border = default_fg
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
proc show(time: string, next_fuzzy: bool = false) =
|
proc show(time: string, next_fuzzy: bool = false) =
|
||||||
|
@ -94,10 +85,7 @@ proc show(time: string, next_fuzzy: bool = false) =
|
||||||
let t = now().format("HH:mm:ss")
|
let t = now().format("HH:mm:ss")
|
||||||
show(t, true)
|
show(t, true)
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
proc main() =
|
|
||||||
let time = getFuzzyTime()
|
let time = getFuzzyTime()
|
||||||
show(time)
|
show(time)
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,10 +1,12 @@
|
||||||
import ../../globurrl
|
import os
|
||||||
import std/[os,osproc,strutils,sequtils]
|
import osproc
|
||||||
|
import strutils
|
||||||
|
import sequtils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const default_fg = black
|
|
||||||
const default_bg = purple
|
|
||||||
const mng_cmd = "alacritty -e nmtui-connect"
|
const mng_cmd = "alacritty -e nmtui-connect"
|
||||||
const nics: seq[string] = @["wlan0","bridge0", "enp3s0","wlp2s0","enp0s20f0u3"]
|
|
||||||
|
|
||||||
proc getIP(nic: string): string =
|
proc getIP(nic: string): string =
|
||||||
let cmd = "ifconfig " & nic & " | grep inet | awk -F\" \" '{print $2}' | head -1 | awk '{print $1}'"
|
let cmd = "ifconfig " & nic & " | grep inet | awk -F\" \" '{print $2}' | head -1 | awk '{print $1}'"
|
||||||
|
@ -29,10 +31,6 @@ proc getConnState(nic: string): (string, string) =
|
||||||
|
|
||||||
proc getObject(): Info =
|
proc getObject(): Info =
|
||||||
var data = newInfo("Netwurrk")
|
var data = newInfo("Netwurrk")
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
# i3bar stuff
|
|
||||||
data.border = default_bg
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
proc getNetInfo*(my_nics: seq[string]) =
|
proc getNetInfo*(my_nics: seq[string]) =
|
||||||
|
@ -59,8 +57,6 @@ proc getNics*(): seq[string] =
|
||||||
return my_nics
|
return my_nics
|
||||||
return @["no-nic"]
|
return @["no-nic"]
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
getNetInfo(getNics())
|
getNetInfo(getNics())
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,5 +1,10 @@
|
||||||
import ../../globurrl.nim
|
import os
|
||||||
import std/[os,osproc,re,strutils]
|
import osproc
|
||||||
|
import re
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const pw_store = getHomeDir() & ".password-store/"
|
const pw_store = getHomeDir() & ".password-store/"
|
||||||
var passwords: seq[string] = @[]
|
var passwords: seq[string] = @[]
|
||||||
|
@ -20,12 +25,9 @@ proc getPasswords(): seq[string] =
|
||||||
proc passwordToClipboard(password: string) =
|
proc passwordToClipboard(password: string) =
|
||||||
discard execCmd("pass show -c " & password)
|
discard execCmd("pass show -c " & password)
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
var info = newInfo("Passwurrd")
|
var info = newInfo("Passwurrd")
|
||||||
var pws = getPasswords()
|
var pws = getPasswords()
|
||||||
let output = outputData(info,pws)
|
let output = outputData(info,pws)
|
||||||
if output in passwords:
|
if output in passwords:
|
||||||
passwordToClipboard(output)
|
passwordToClipboard(output)
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
main()
|
|
|
@ -1,15 +1,11 @@
|
||||||
import ../../globurrl
|
import osproc
|
||||||
import std/[osproc, re, strutils]
|
import re
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const host: string = "9.9.9.9"
|
const host: string = "9.9.9.9"
|
||||||
const default_bg = blue
|
|
||||||
const default_fg = white
|
|
||||||
const medium_bg = alert
|
|
||||||
const medium_fg = black
|
|
||||||
const alert_bg = alert
|
|
||||||
const alert_fg = black
|
|
||||||
const warning_bg = red
|
|
||||||
const warning_fg = white
|
|
||||||
|
|
||||||
let ping_re = re(r"time=[0-9.]+")
|
let ping_re = re(r"time=[0-9.]+")
|
||||||
const ping_cmd: string = "ping -4 -c 1 " & host
|
const ping_cmd: string = "ping -4 -c 1 " & host
|
||||||
|
@ -47,39 +43,13 @@ proc getObject(ping: float): Info =
|
||||||
var data = newInfo("Ping Clurrk")
|
var data = newInfo("Ping Clurrk")
|
||||||
data.full_text = text
|
data.full_text = text
|
||||||
# i3bar stuff
|
# i3bar stuff
|
||||||
data.color = default_fg
|
|
||||||
data.border = default_bg
|
|
||||||
data.background = black
|
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
case state:
|
|
||||||
of 1:
|
|
||||||
data.selected_bg = medium_bg
|
|
||||||
data.selected_fg = medium_fg
|
|
||||||
# i3bar stuff
|
|
||||||
data.color = medium_bg
|
|
||||||
of 2:
|
|
||||||
data.selected_bg = alert_bg
|
|
||||||
data.selected_fg = alert_fg
|
|
||||||
# i3bar stuff
|
|
||||||
data.color = alert_bg
|
|
||||||
of 9:
|
|
||||||
data.selected_bg = warning_bg
|
|
||||||
data.selected_fg = warning_fg
|
|
||||||
# i3bar stuff
|
|
||||||
data.color = warning_bg
|
|
||||||
else:
|
|
||||||
#default options already set
|
|
||||||
let ok = true
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
let ping = get_ping()
|
let ping = get_ping()
|
||||||
let data = getObject(ping)
|
let data = getObject(ping)
|
||||||
let output = outputData(data)
|
let output = outputData(data)
|
||||||
if output == data.full_text:
|
if output == data.full_text:
|
||||||
main()
|
go()
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
65
src/util/pw_generaturr.nim
Normal file
65
src/util/pw_generaturr.nim
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
import httpclient
|
||||||
|
import json
|
||||||
|
import strutils
|
||||||
|
import random
|
||||||
|
|
||||||
|
import ../parser
|
||||||
|
import ../model/pwgen
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
|
var passwords: seq[string]
|
||||||
|
proc getNumber(size: int = 4): string =
|
||||||
|
var num = ""
|
||||||
|
for _ in countup(1,size):
|
||||||
|
randomize()
|
||||||
|
let roll = rand(0..9)
|
||||||
|
num &= $roll
|
||||||
|
return num
|
||||||
|
|
||||||
|
proc parsePasswords(body: string, digits: int) =
|
||||||
|
passwords = @[]
|
||||||
|
let j = body.parseJson
|
||||||
|
for pass in j.getElems:
|
||||||
|
var p = pass.getStr.capitalizeAscii
|
||||||
|
p &= getNumber(digits)
|
||||||
|
passwords.add(p)
|
||||||
|
|
||||||
|
proc getPasswords(pwgen: PWGen) =
|
||||||
|
var c = newHttpClient()
|
||||||
|
try:
|
||||||
|
let url = "https://random-word-api.herokuapp.com/word?number=" & $pwgen.number & "&length=" & $pwgen.word_len
|
||||||
|
let resp = c.get(url)
|
||||||
|
if resp.status == $Http200:
|
||||||
|
parsePasswords(resp.body, pwgen.digits)
|
||||||
|
except:
|
||||||
|
stderr.writeLine getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
proc getOutput(): Info =
|
||||||
|
var data = newInfo("PW Generaturr")
|
||||||
|
data.full_text = "Refresh"
|
||||||
|
return data
|
||||||
|
|
||||||
|
proc goOutput(args: PWGen) =
|
||||||
|
let data = getoutput()
|
||||||
|
let selected = outputData(data,passwords)
|
||||||
|
if selected in passwords:
|
||||||
|
copyToClipboard(selected)
|
||||||
|
elif selected == "Refresh":
|
||||||
|
getPasswords(args)
|
||||||
|
goOutput(args)
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
echo "Getting passwords..."
|
||||||
|
let args = parsePWGenArgs()
|
||||||
|
getPasswords(args)
|
||||||
|
if args.to_terminal:
|
||||||
|
for pw in passwords:
|
||||||
|
echo pw
|
||||||
|
else:
|
||||||
|
echo "Outputting to app"
|
||||||
|
goOutput(args)
|
||||||
|
|
||||||
|
if isMainModule:
|
||||||
|
go()
|
|
@ -1,20 +1,18 @@
|
||||||
import ../../globurrl
|
import os
|
||||||
import std/[os,osproc,tables,algorithm]
|
import osproc
|
||||||
|
import tables
|
||||||
|
import algorithm
|
||||||
|
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const REMMINA_DIR = getHomeDir() & ".local/share/remmina"
|
const REMMINA_DIR = getHomeDir() & ".local/share/remmina"
|
||||||
const SWITCH_WS = false
|
|
||||||
const REMMINA_WS = "4"
|
|
||||||
|
|
||||||
var sessions = initTable[string,string]()
|
var sessions = initTable[string,string]()
|
||||||
var names: seq[string] = @[]
|
var names: seq[string] = @[]
|
||||||
|
|
||||||
proc main()
|
|
||||||
|
|
||||||
proc switchWorkspace() =
|
|
||||||
if SWITCH_WS and REMMINA_WS != "":
|
|
||||||
discard execCmd("i3-msg workspace number " & REMMINA_WS)
|
|
||||||
|
|
||||||
proc getRemminaFiles(): seq[string] =
|
proc getRemminaFiles(): seq[string] =
|
||||||
if len(names) < 1:
|
if len(names) < 1:
|
||||||
for file in walkFiles(REMMINA_DIR & "/*.remmina"):
|
for file in walkFiles(REMMINA_DIR & "/*.remmina"):
|
||||||
|
@ -38,6 +36,8 @@ proc startRemmina(conn: string) =
|
||||||
let session = sessions[conn]
|
let session = sessions[conn]
|
||||||
discard execCmd("remmina -c " & quote(session))
|
discard execCmd("remmina -c " & quote(session))
|
||||||
|
|
||||||
|
proc go*() # adding as need to refer back to it in selectRemmina
|
||||||
|
|
||||||
proc selectRemmina(conn: string) =
|
proc selectRemmina(conn: string) =
|
||||||
var info = newInfo("Remmina Choosurr : " & conn)
|
var info = newInfo("Remmina Choosurr : " & conn)
|
||||||
let args = @["connect", "edit", "back"]
|
let args = @["connect", "edit", "back"]
|
||||||
|
@ -51,11 +51,9 @@ proc selectRemmina(conn: string) =
|
||||||
editRemmina(conn)
|
editRemmina(conn)
|
||||||
#switchWorkspace()
|
#switchWorkspace()
|
||||||
of "back":
|
of "back":
|
||||||
main()
|
go()
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
|
||||||
proc main() =
|
|
||||||
var info = newInfo("Remmina Choosurr")
|
var info = newInfo("Remmina Choosurr")
|
||||||
var args: seq[string] = getRemminaFiles()
|
var args: seq[string] = getRemminaFiles()
|
||||||
args.add("new")
|
args.add("new")
|
||||||
|
@ -68,7 +66,3 @@ proc main() =
|
||||||
elif output in names:
|
elif output in names:
|
||||||
selectRemmina(output)
|
selectRemmina(output)
|
||||||
return
|
return
|
||||||
return
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,23 +1,21 @@
|
||||||
import ../../globurrl
|
import times
|
||||||
import std/[times,os,osproc,strutils,sequtils]
|
import os
|
||||||
|
import osproc
|
||||||
|
import strutils
|
||||||
|
import sequtils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
import ../parser
|
||||||
|
import ../model/screenshot
|
||||||
|
|
||||||
var screenshot_type = ""
|
|
||||||
const TYPES = @["region", "fullscreen", "window"]
|
|
||||||
const DATE_FORMAT = "yyyyMMdd-hhmmss"
|
const DATE_FORMAT = "yyyyMMdd-hhmmss"
|
||||||
const FILENAME = "Screenshot-%d.png"
|
const FILENAME = "Screenshot-%d.png"
|
||||||
const TEMP_DIR = "/tmp/"
|
const TEMP_DIR = "/tmp/"
|
||||||
const SCREENSHOT_CMD = "maim -u %s --format png %f"
|
|
||||||
var RUN_CMD = SCREENSHOT_CMD
|
|
||||||
let DATE_STR = now().format(DATE_FORMAT)
|
let DATE_STR = now().format(DATE_FORMAT)
|
||||||
# where %s is an extra flag or process, i.e. xdotool for getting active window
|
|
||||||
const ACTIVE_WINDOW_CMD = "-i $(xdotool getactivewindow)"
|
|
||||||
const REGION_FLAG = "-s"
|
|
||||||
var REGION_CMD = REGION_FLAG
|
|
||||||
const CLIPBOARD_CMD = "xclip -selection clipboard -t image/png"
|
|
||||||
var CLIP_CMD = CLIPBOARD_CMD
|
|
||||||
|
|
||||||
proc saveToClipboard(filename: string) =
|
proc saveToClipboard(filename: string) =
|
||||||
let cmd = "cat " & filename & " | " & CLIP_CMD
|
let cmd = "cat " & filename & " | " & CLIPBOARD_CMD
|
||||||
let status = execCmd(cmd)
|
let status = execCmd(cmd)
|
||||||
if status == 0 and fileExists(filename):
|
if status == 0 and fileExists(filename):
|
||||||
removeFile(filename)
|
removeFile(filename)
|
||||||
|
@ -54,42 +52,44 @@ proc showScreenshotSaveSel(filename: string) =
|
||||||
openFile(filename)
|
openFile(filename)
|
||||||
return
|
return
|
||||||
|
|
||||||
proc showScreenshotTypeSel() =
|
proc showScreenshotSizeSel(): ScreenshotSize =
|
||||||
let info = newInfo("Screenshurrt type")
|
let info = newInfo("Screenshurrt type")
|
||||||
let args = concat(TYPES,@["---","exit"])
|
let args = concat(ScreenshotSizes(),@["---","exit"])
|
||||||
let choice = outputData(info,args)
|
let choice = outputData(info,args)
|
||||||
if choice in TYPES:
|
if choice.isScreenshotSize():
|
||||||
screenshot_type = choice
|
return choice.toScreenshotSize()
|
||||||
elif choice == "---":
|
elif choice == "---":
|
||||||
showScreenshotTypeSel()
|
return showScreenshotSizeSel()
|
||||||
elif choice == "exit":
|
elif choice == "exit":
|
||||||
return
|
quit(0)
|
||||||
return
|
else:
|
||||||
|
quit(0)
|
||||||
|
|
||||||
proc takeScreenshot() =
|
proc takeScreenshot(ss: Screenshot) =
|
||||||
let filename = TEMP_DIR & FILENAME.replace("%d",DATE_STR)
|
let filename = TEMP_DIR & FILENAME.replace("%d",DATE_STR)
|
||||||
var cmd = RUN_CMD.replace("%f",filename)
|
var cmd = ss.tool.command
|
||||||
case screenshot_type:
|
case ss.size:
|
||||||
of "window":
|
of Window:
|
||||||
cmd = cmd.replace("%s",ACTIVE_WINDOW_CMD)
|
cmd = ss.tool.activeWindowCommand()
|
||||||
of "region":
|
of Region:
|
||||||
cmd = cmd.replace("%s",REGION_CMD)
|
cmd = ss.tool.regionCommand()
|
||||||
else: #fullscreen
|
else: #fullscreen
|
||||||
cmd = cmd.replace("%s","")
|
cmd = cmd.replace("%s","")
|
||||||
# sleep for a bit otherwise the screen shot grabs dmenu as well
|
# sleep for a bit otherwise the screen shot could grabs dmenu as well
|
||||||
sleep(1*500)
|
sleep(1*500)
|
||||||
|
cmd = cmd.replace("%f",filename)
|
||||||
|
echo "Running command:\n" & cmd
|
||||||
let status = execCmd(cmd)
|
let status = execCmd(cmd)
|
||||||
if status == 0:
|
if status == 0:
|
||||||
showScreenshotSaveSel(filename)
|
showScreenshotSaveSel(filename)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
var ss = parseScreenshotArgs()
|
||||||
|
if ss.size == None:
|
||||||
|
ss.size = showScreenshotSizeSel()
|
||||||
|
if ss.size != None:
|
||||||
|
ss.takeScreenshot()
|
||||||
|
|
||||||
if isMainModule:
|
if isMainModule:
|
||||||
for arg in args:
|
go()
|
||||||
if arg in TYPES:
|
|
||||||
screenshot_type = arg
|
|
||||||
break
|
|
||||||
if screenshot_type == "":
|
|
||||||
showScreenshotTypeSel()
|
|
||||||
if screenshot_type != "":
|
|
||||||
takeScreenshot()
|
|
54
src/util/temperaturr.nim
Normal file
54
src/util/temperaturr.nim
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import math
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
|
proc getThermalZones(): seq[string] =
|
||||||
|
var zones: seq[string] = @[]
|
||||||
|
let dirname_re = re("thermal_zone[\\d]+")
|
||||||
|
let enabled_re = re("enabled")
|
||||||
|
for file in walkDir("/sys/class/thermal/"):
|
||||||
|
if file.path.contains(dirname_re):
|
||||||
|
let state = readFile(file.path & "/mode")
|
||||||
|
if state.contains(enabled_re):
|
||||||
|
zones.add(file.path)
|
||||||
|
return zones
|
||||||
|
|
||||||
|
proc getTemp(zone: string): int =
|
||||||
|
let temp = strip(readFile(zone & "/temp"))
|
||||||
|
return parseInt(temp)
|
||||||
|
|
||||||
|
proc getAverageTemp(zones: seq[string]): float =
|
||||||
|
var temps: int = 0
|
||||||
|
for zone in zones:
|
||||||
|
let temp = getTemp(zone)
|
||||||
|
temps += temp
|
||||||
|
let avgtemp = ceil((temps / len(zones))/1000)
|
||||||
|
return round(avgtemp,2)
|
||||||
|
|
||||||
|
proc getObject(temp: float): Info =
|
||||||
|
var icon = ""
|
||||||
|
case temp:
|
||||||
|
of 40..59:
|
||||||
|
icon = ""
|
||||||
|
of 60.. 200:
|
||||||
|
icon = ""
|
||||||
|
else:
|
||||||
|
icon = ""
|
||||||
|
let main_text = icon & " " & $temp & "°C"
|
||||||
|
var data = newInfo("Temperaturr")
|
||||||
|
data.full_text = main_text
|
||||||
|
return data
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
let zones = getThermalZones()
|
||||||
|
let temp = getAverageTemp(zones)
|
||||||
|
let data = getObject(temp)
|
||||||
|
let option = outputData(data)
|
||||||
|
if option == data.full_text:
|
||||||
|
# Refresh
|
||||||
|
go()
|
||||||
|
|
110
src/util/tideurrl.nim
Normal file
110
src/util/tideurrl.nim
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#curl https://www.tidetimes.org.uk/exmouth-dock-tide-times-20190101 | grep -E -o ">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))"
|
||||||
|
|
||||||
|
import re
|
||||||
|
import httpclient
|
||||||
|
import times
|
||||||
|
import osproc
|
||||||
|
import sequtils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../parser
|
||||||
|
import ../output
|
||||||
|
import ../model/tides
|
||||||
|
|
||||||
|
const icon: string = "🌊 "
|
||||||
|
|
||||||
|
proc sortTides(tides: seq[Tide], is_tomorrow: bool = false): seq[Tide] =
|
||||||
|
let timenow = now()
|
||||||
|
var reltides: seq[Tide]
|
||||||
|
for tide in tides:
|
||||||
|
if timenow.format("HH:MM") <= tide.time and not is_tomorrow:
|
||||||
|
reltides.add(tide)
|
||||||
|
elif is_tomorrow:
|
||||||
|
reltides.add(tide)
|
||||||
|
return reltides
|
||||||
|
|
||||||
|
|
||||||
|
proc getTideData(mytides: TideList, get_tomorrow: bool = false): seq[Tide] =
|
||||||
|
var tides: seq[Tide]
|
||||||
|
let fnd = re">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))"
|
||||||
|
var client = newHttpClient(timeout = 10000)
|
||||||
|
var link = replace(mytides.url,re"\%LOC",mytides.location)
|
||||||
|
if get_tomorrow:
|
||||||
|
let tomdate = now() + initTimeInterval(days = 1)
|
||||||
|
link &= "-" & tomdate.format("yyyyMMdd")
|
||||||
|
try:
|
||||||
|
# Remember to compile with -d:ssl else this won't work
|
||||||
|
let resp = client.request(link)
|
||||||
|
if resp.status != $Http200 or resp.body == "":
|
||||||
|
var data = newInfo("Tideurrl")
|
||||||
|
data.full_text = "Error Response: " & resp.status & ":\nBody:" & resp.body
|
||||||
|
discard outputData(data)
|
||||||
|
return @[]
|
||||||
|
let data = resp.body
|
||||||
|
let times = findAll(data,fnd)
|
||||||
|
var tide: Tide
|
||||||
|
var column = 0
|
||||||
|
for idx,time in times:
|
||||||
|
if idx == 12:
|
||||||
|
break
|
||||||
|
let l = len(time) - 1
|
||||||
|
if time == ">High" or time == ">Low":
|
||||||
|
tide = Tide()
|
||||||
|
tide.state = time[1..l]
|
||||||
|
column = 1
|
||||||
|
continue
|
||||||
|
elif column == 1:
|
||||||
|
tide.time = time[1..l]
|
||||||
|
column = 2
|
||||||
|
continue
|
||||||
|
elif column == 2:
|
||||||
|
tide.height = time[1..l]
|
||||||
|
tides.add(tide)
|
||||||
|
column = 0
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
var data = newInfo("Tideurrl")
|
||||||
|
data.full_text = "Unable to get Tide Data : " & getCurrentExceptionMsg()
|
||||||
|
discard outputData(data)
|
||||||
|
return tides
|
||||||
|
|
||||||
|
proc getDesign(tl: TideList): Info =
|
||||||
|
var my_tides: seq[string] = @[]
|
||||||
|
my_tides.add(tl.location)
|
||||||
|
let tides = tl.tides
|
||||||
|
for tide in tides:
|
||||||
|
let str = icon & tide.state[0] & " " & tide.time & " " & tide.height
|
||||||
|
my_tides.add(str)
|
||||||
|
var data = newInfo("Tideurrl")
|
||||||
|
data.args = my_tides
|
||||||
|
return data
|
||||||
|
|
||||||
|
proc getTides*(mytides: var TideList, get_tomorrow: bool = false) =
|
||||||
|
mytides.tides = mytides.getTideData(get_tomorrow)
|
||||||
|
mytides.tides = sortTides(mytides.tides, get_tomorrow)
|
||||||
|
if len(mytides.tides) == 0:
|
||||||
|
return
|
||||||
|
let data = getDesign(mytides)
|
||||||
|
var opt_tomorrow = "tomorrow"
|
||||||
|
if get_tomorrow:
|
||||||
|
opt_tomorrow = "back"
|
||||||
|
let args = concat(data.args,@["---",opt_tomorrow])
|
||||||
|
let output = outputData(data,args)
|
||||||
|
if output == "tomorrow":
|
||||||
|
getTides(mytides,true)
|
||||||
|
elif output == "back":
|
||||||
|
getTides(mytides)
|
||||||
|
elif output == "---" or output == "":
|
||||||
|
return
|
||||||
|
elif output in args:
|
||||||
|
let url = replace(mytides.url,re"\%LOC",mytides.location)
|
||||||
|
discard execCmd("xdg-open " & url)
|
||||||
|
else:
|
||||||
|
mytides.location = output
|
||||||
|
getTides(mytides)
|
||||||
|
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
var mytides = parseTideurrlArgs()
|
||||||
|
getTides(mytides)
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import ../../globurrl
|
import os
|
||||||
import std/[os,strutils,sequtils,osproc]
|
import strutils
|
||||||
|
import sequtils
|
||||||
|
import osproc
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
import ../parser
|
||||||
|
import ../model/volume
|
||||||
|
|
||||||
const audio_tools = @["ncpamixer", "pavucontrol"]
|
const audio_tools = @["ncpamixer", "pavucontrol"]
|
||||||
const vol_cmd = "pamixer"
|
const vol_cmd = "pamixer"
|
||||||
|
@ -10,11 +17,14 @@ const vol_mute = vol_cmd & " -t"
|
||||||
const vol_default_by = "5"
|
const vol_default_by = "5"
|
||||||
const vol_get = vol_cmd & " --get-volume"
|
const vol_get = vol_cmd & " --get-volume"
|
||||||
const vol_get_mute = vol_cmd & " --get-mute"
|
const vol_get_mute = vol_cmd & " --get-mute"
|
||||||
const default_bg = green
|
|
||||||
const default_fg = black
|
|
||||||
|
|
||||||
|
|
||||||
proc getCurrentVolume(): string {.gcsafe.}
|
proc getCurrentVolume(): string =
|
||||||
|
let mute = execCmdEx(vol_get_mute)
|
||||||
|
if strip(mute.output) == "true":
|
||||||
|
return "muted"
|
||||||
|
let vol = execCmdEx(vol_get)
|
||||||
|
return vol.output
|
||||||
|
|
||||||
proc checkVolume(volume: string): string =
|
proc checkVolume(volume: string): string =
|
||||||
var vol = volume
|
var vol = volume
|
||||||
|
@ -24,11 +34,11 @@ proc checkVolume(volume: string): string =
|
||||||
vol = checkVolume(vol)
|
vol = checkVolume(vol)
|
||||||
return vol
|
return vol
|
||||||
|
|
||||||
proc getDesign(volume: string): (string,string) =
|
proc getDesign(volume: string): string =
|
||||||
let vol = checkVolume(volume)
|
let vol = checkVolume(volume)
|
||||||
var icon = " "
|
var icon = " "
|
||||||
if vol == "muted":
|
if vol == "muted":
|
||||||
return (icon & "muted", icon & "muted")
|
return icon & "muted"
|
||||||
let pcnt = parseInt(strip(vol))
|
let pcnt = parseInt(strip(vol))
|
||||||
case pcnt:
|
case pcnt:
|
||||||
of 85..100:
|
of 85..100:
|
||||||
|
@ -42,15 +52,7 @@ proc getDesign(volume: string): (string,string) =
|
||||||
else:
|
else:
|
||||||
icon = " "
|
icon = " "
|
||||||
let main_text = icon & $pcnt & "%"
|
let main_text = icon & $pcnt & "%"
|
||||||
let text = "<span size=\"x-large\">" & icon & "</span>" & $pcnt & "%"
|
return main_text
|
||||||
return (text, main_text)
|
|
||||||
|
|
||||||
proc getCurrentVolume(): string =
|
|
||||||
let mute = execCmdEx(vol_get_mute)
|
|
||||||
if strip(mute.output) == "true":
|
|
||||||
return "muted"
|
|
||||||
let vol = execCmdEx(vol_get)
|
|
||||||
return vol.output
|
|
||||||
|
|
||||||
proc volumeUp() =
|
proc volumeUp() =
|
||||||
let cmd = replace(vol_up, "%v", vol_default_by)
|
let cmd = replace(vol_up, "%v", vol_default_by)
|
||||||
|
@ -63,18 +65,11 @@ proc volumeDown() =
|
||||||
proc volumeMute() =
|
proc volumeMute() =
|
||||||
discard execCmd(vol_mute)
|
discard execCmd(vol_mute)
|
||||||
|
|
||||||
proc getVolume*(run_once: bool = false) =
|
proc getVolume*() =
|
||||||
let vol = getCurrentVolume()
|
let vol = getCurrentVolume()
|
||||||
let (text, main_text) = getDesign(vol)
|
let main_text = getDesign(vol)
|
||||||
var data = newInfo("Volurrme")
|
var data = newInfo("Volurrme")
|
||||||
data.full_text = main_text
|
data.full_text = main_text
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
# i3bar stuff
|
|
||||||
data.html_text = text
|
|
||||||
data.color = foreground
|
|
||||||
data.border = green
|
|
||||||
data.background = black
|
|
||||||
let args = concat(@["up", "down", "mute", "---", "exit", "---"],audio_tools)
|
let args = concat(@["up", "down", "mute", "---", "exit", "---"],audio_tools)
|
||||||
let option = outputData(data,args)
|
let option = outputData(data,args)
|
||||||
if option == "":
|
if option == "":
|
||||||
|
@ -101,26 +96,20 @@ proc getVolume*(run_once: bool = false) =
|
||||||
try:
|
try:
|
||||||
let vol = parseInt(option)
|
let vol = parseInt(option)
|
||||||
let cmd = replace(vol_set, "%v", $vol)
|
let cmd = replace(vol_set, "%v", $vol)
|
||||||
let x = execCmd(cmd)
|
discard execCmd(cmd)
|
||||||
getVolume()
|
getVolume()
|
||||||
except:
|
except:
|
||||||
echo getCurrentExceptionMsg()
|
echo getCurrentExceptionMsg()
|
||||||
getVolume()
|
getVolume()
|
||||||
|
|
||||||
proc main() =
|
proc go*() =
|
||||||
getVolume()
|
let arg = parseVolArgs()
|
||||||
|
case arg
|
||||||
if isMainModule:
|
of VolUp:
|
||||||
block start:
|
volumeUp()
|
||||||
for arg in args:
|
of VolDown:
|
||||||
case arg:
|
volumeDown()
|
||||||
of "up":
|
of VolMute:
|
||||||
volumeUp()
|
volumeMute()
|
||||||
break start
|
else:
|
||||||
of "down":
|
getVolume()
|
||||||
volumeDown()
|
|
||||||
break start
|
|
||||||
of "mute":
|
|
||||||
volumeMute()
|
|
||||||
break start
|
|
||||||
main()
|
|
|
@ -1,9 +1,11 @@
|
||||||
import ../../globurrl
|
import os
|
||||||
import std/[os,osproc,strutils,sequtils]
|
import osproc
|
||||||
|
import strutils
|
||||||
|
import sequtils
|
||||||
|
|
||||||
|
import ../common
|
||||||
|
import ../output
|
||||||
|
|
||||||
const default_bg = purple
|
|
||||||
const default_fg = white
|
|
||||||
const wlan_nics: seq[string] = @["wlan0"]
|
|
||||||
const get_ssid_cmd = "iwgetid -r"
|
const get_ssid_cmd = "iwgetid -r"
|
||||||
const mng_cmd = "alacritty -e nmtui-connect"
|
const mng_cmd = "alacritty -e nmtui-connect"
|
||||||
|
|
||||||
|
@ -28,9 +30,6 @@ proc getWifi(nic: string): (string, string) =
|
||||||
|
|
||||||
proc getObject(): Info =
|
proc getObject(): Info =
|
||||||
var data = newInfo("Wirelurrs")
|
var data = newInfo("Wirelurrs")
|
||||||
data.border = purple
|
|
||||||
data.selected_bg = default_bg
|
|
||||||
data.selected_fg = default_fg
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
proc getWifiInfo*(nics: seq[string]) =
|
proc getWifiInfo*(nics: seq[string]) =
|
||||||
|
@ -41,6 +40,8 @@ proc getWifiInfo*(nics: seq[string]) =
|
||||||
let data = getObject()
|
let data = getObject()
|
||||||
let args = concat(lst,@["---", "manage","exit"])
|
let args = concat(lst,@["---", "manage","exit"])
|
||||||
let output = outputData(data, args)
|
let output = outputData(data, args)
|
||||||
|
if output in lst:
|
||||||
|
discard execCmd(mng_cmd)
|
||||||
case output:
|
case output:
|
||||||
of "manage":
|
of "manage":
|
||||||
discard execCmd(mng_cmd)
|
discard execCmd(mng_cmd)
|
||||||
|
@ -49,16 +50,20 @@ proc getWifiInfo*(nics: seq[string]) =
|
||||||
of "---":
|
of "---":
|
||||||
return
|
return
|
||||||
|
|
||||||
proc main() =
|
proc getWiFiNICs(): seq[string] =
|
||||||
var my_nics: seq[string] = @[]
|
var my_nics: seq[string] = @[]
|
||||||
for nic in wlan_nics:
|
for path in walkDir("/sys/class/net/"):
|
||||||
if dirExists("/sys/class/net/" & nic):
|
if dirExists(path.path & "/wireless"):
|
||||||
|
let nic = path.path.replace("/sys/class/net/","")
|
||||||
my_nics.add(nic)
|
my_nics.add(nic)
|
||||||
|
return my_nics
|
||||||
|
|
||||||
|
proc go*() =
|
||||||
|
let my_nics = getWiFiNICs()
|
||||||
if len(my_nics) > 0:
|
if len(my_nics) > 0:
|
||||||
getWifiInfo(my_nics)
|
getWifiInfo(my_nics)
|
||||||
else:
|
else:
|
||||||
switchTwmMode()
|
var data = getObject()
|
||||||
echo "No WLAN"
|
data.full_text = "No WLAN"
|
||||||
|
discard outputData(data)
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
11
src/wmtools.nim
Normal file
11
src/wmtools.nim
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is just an example to get you started. A typical binary package
|
||||||
|
# uses this file as the main entry point of the application.
|
||||||
|
#
|
||||||
|
|
||||||
|
import common
|
||||||
|
import parser
|
||||||
|
import dispatcher
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
parseArgs()
|
||||||
|
dispatch myConfig
|
|
@ -1,72 +0,0 @@
|
||||||
import ../../globurrl
|
|
||||||
import std/[os,re,math,strutils]
|
|
||||||
|
|
||||||
const default_bg = green
|
|
||||||
const default_fg = black
|
|
||||||
const alert_bg = yellow
|
|
||||||
const alert_fg = black
|
|
||||||
const warning_bg = red
|
|
||||||
const warning_fg = black
|
|
||||||
|
|
||||||
proc getThermalZones(): seq[string] =
|
|
||||||
var zones: seq[string] = @[]
|
|
||||||
let dirname = re("thermal_zone[\\d]+")
|
|
||||||
for file in walkDir("/sys/class/thermal/"):
|
|
||||||
if contains(file.path,dirname):
|
|
||||||
let state = readFile(file.path & "/mode")
|
|
||||||
if contains(state,re"enabled"):
|
|
||||||
zones.add(file.path)
|
|
||||||
return zones
|
|
||||||
|
|
||||||
proc getTemp(zone: string): int =
|
|
||||||
let temp = strip(readFile(zone & "/temp"))
|
|
||||||
return parseInt(temp)
|
|
||||||
|
|
||||||
proc getAverageTemp(zones: seq[string]): int =
|
|
||||||
var temps: int = 0
|
|
||||||
for zone in zones:
|
|
||||||
let temp = getTemp(zone)
|
|
||||||
temps += temp
|
|
||||||
let avgtemp = ceil((temps / len(zones))/1000)
|
|
||||||
return toInt(round(avgtemp,0))
|
|
||||||
|
|
||||||
proc getObject(temp: int): Info =
|
|
||||||
var icon = ""
|
|
||||||
var bg_col = default_bg
|
|
||||||
var fg_col = default_fg
|
|
||||||
case temp:
|
|
||||||
of 40..59:
|
|
||||||
bg_col = alert_bg
|
|
||||||
fg_col = alert_fg
|
|
||||||
icon = ""
|
|
||||||
of 60.. 200:
|
|
||||||
bg_col = warning_bg
|
|
||||||
fg_col = warning_fg
|
|
||||||
icon = ""
|
|
||||||
else:
|
|
||||||
bg_col = default_bg
|
|
||||||
fg_col = default_fg
|
|
||||||
icon = ""
|
|
||||||
let text = "<span foreground='" & bg_col & "'>" & icon & "</span> " & $temp & "°C"
|
|
||||||
let main_text = icon & " " & $temp & "°C"
|
|
||||||
var data = newInfo("Temperaturr")
|
|
||||||
data.full_text = main_text
|
|
||||||
data.selected_bg = bg_col
|
|
||||||
data.selected_fg = fg_col
|
|
||||||
# i3bar stuff
|
|
||||||
data.html_text = text
|
|
||||||
data.color = bg_col
|
|
||||||
data.border = bg_col
|
|
||||||
return data
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
let zones = getThermalZones()
|
|
||||||
let temp = getAverageTemp(zones)
|
|
||||||
let data = getObject(temp)
|
|
||||||
let option = outputData(data)
|
|
||||||
if option == data.full_text:
|
|
||||||
# Refresh
|
|
||||||
main()
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Display temp in dmenu"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["temperaturr"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,106 +0,0 @@
|
||||||
#curl https://www.tidetimes.org.uk/exmouth-dock-tide-times-20190101 | grep -E -o ">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))"
|
|
||||||
import ../../globurrl
|
|
||||||
import std/[re,httpclient,times,osproc,sequtils]
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# Pass location in as variable
|
|
||||||
|
|
||||||
const url* = "https://www.tidetimes.org.uk/%LOC-tide-times"
|
|
||||||
const loc* = "exmouth-dock"
|
|
||||||
const icon: string = "🌊 "
|
|
||||||
|
|
||||||
type
|
|
||||||
Tide = ref object
|
|
||||||
State: string
|
|
||||||
Time: string
|
|
||||||
Height: string
|
|
||||||
Tomorrow: bool
|
|
||||||
TideList = ref object
|
|
||||||
Tides: seq[Tide]
|
|
||||||
LastUpdated: DateTime
|
|
||||||
|
|
||||||
proc sortTides(tides: seq[Tide], is_tomorrow: bool = false): seq[Tide] =
|
|
||||||
let timenow = now()
|
|
||||||
var reltides: seq[Tide]
|
|
||||||
for tide in tides:
|
|
||||||
if timenow.format("HH:MM") <= tide.Time and not is_tomorrow:
|
|
||||||
reltides.add(tide)
|
|
||||||
elif is_tomorrow:
|
|
||||||
reltides.add(tide)
|
|
||||||
return reltides
|
|
||||||
|
|
||||||
|
|
||||||
proc getTideData(get_tomorrow: bool = false): seq[Tide] =
|
|
||||||
var tides: seq[Tide]
|
|
||||||
let fnd = re">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))"
|
|
||||||
var client = newHttpClient()
|
|
||||||
var link = replace(url,re"\%LOC",loc)
|
|
||||||
if get_tomorrow:
|
|
||||||
let tomdate = now() + initTimeInterval(days = 1)
|
|
||||||
link &= "-" & tomdate.format("yyyyMMdd")
|
|
||||||
try:
|
|
||||||
# Remember to compile with -d:ssl else this won't work
|
|
||||||
let data = client.getContent(link)
|
|
||||||
let times = findAll(data,fnd)
|
|
||||||
var tide: Tide
|
|
||||||
var column = 0
|
|
||||||
for idx,time in times:
|
|
||||||
if idx == 12:
|
|
||||||
break
|
|
||||||
let l = len(time) - 1
|
|
||||||
if time == ">High" or time == ">Low":
|
|
||||||
tide = Tide()
|
|
||||||
tide.State = time[1..l]
|
|
||||||
column = 1
|
|
||||||
continue
|
|
||||||
elif column == 1:
|
|
||||||
tide.Time = time[1..l]
|
|
||||||
column = 2
|
|
||||||
continue
|
|
||||||
elif column == 2:
|
|
||||||
tide.Height = time[1..l]
|
|
||||||
tides.add(tide)
|
|
||||||
column = 0
|
|
||||||
continue
|
|
||||||
except:
|
|
||||||
echo "Unable to get Tide Data : " & getCurrentExceptionMsg()
|
|
||||||
return tides
|
|
||||||
|
|
||||||
proc getDesign(tides: seq[Tide]): Info =
|
|
||||||
var my_tides: seq[string] = @[]
|
|
||||||
for tide in tides:
|
|
||||||
let str = icon & tide.State[0] & " " & tide.Time & " " & tide.Height
|
|
||||||
my_tides.add(str)
|
|
||||||
var data = newInfo("Tideurrl")
|
|
||||||
data.border = black
|
|
||||||
data.args = my_tides
|
|
||||||
return data
|
|
||||||
|
|
||||||
proc getTides*(get_tomorrow: bool = false) =
|
|
||||||
var mytides = TideList()
|
|
||||||
mytides.Tides = getTideData(get_tomorrow)
|
|
||||||
mytides.Tides = sortTides(mytides.Tides, get_tomorrow)
|
|
||||||
if len(mytides.Tides) == 0:
|
|
||||||
getTides(true)
|
|
||||||
return
|
|
||||||
let data = getDesign(mytides.Tides)
|
|
||||||
var opt_tomorrow = "tomorrow"
|
|
||||||
if get_tomorrow:
|
|
||||||
opt_tomorrow = "back"
|
|
||||||
let args = concat(data.args,@["---",opt_tomorrow])
|
|
||||||
let output = outputData(data,args)
|
|
||||||
if output == "tomorrow":
|
|
||||||
getTides(true)
|
|
||||||
elif output == "back":
|
|
||||||
getTides()
|
|
||||||
elif output == "---":
|
|
||||||
return
|
|
||||||
elif output in args:
|
|
||||||
let url = replace(url,re"\%LOC",loc)
|
|
||||||
discard execCmd("xdg-open " & url)
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
getTides()
|
|
||||||
|
|
||||||
if isMainModule:
|
|
||||||
main()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Display local tides in dmenu"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["tideurrl"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1 +0,0 @@
|
||||||
-d:ssl
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Display and control volume with dmenu"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["volurrme"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Paul Wilde"
|
|
||||||
description = "Display and control WLAN state with dmenu"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["wirelurrs"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 1.6.6"
|
|
16
wm_tools.nimble
Normal file
16
wm_tools.nimble
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Package
|
||||||
|
|
||||||
|
version = "2.0.1"
|
||||||
|
author = "Paul Wilde"
|
||||||
|
description = "A set of informational tools"
|
||||||
|
license = "AGPL-3.0-or-later"
|
||||||
|
srcDir = "src"
|
||||||
|
bin = @["wmtools"]
|
||||||
|
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 2.0.0"
|
||||||
|
requires "parsetoml >= 0.7.1"
|
||||||
|
requires "argparse"
|
||||||
|
requires "configparser"
|
Loading…
Reference in a new issue