"""
domonic.terminal
====================================
- call command line functions in python 3
"""
import os
import subprocess
from domonic.javascript import window
[docs]class TerminalException(Exception):
"""raised if the terminal throws an exception"""
def __init__(self, error, message="An error message was recieved from terminal"):
print(error, message)
self.message = message
super().__init__(self.message)
[docs]class command:
"""wrapper class for all terminal commands"""
[docs] @staticmethod
def run(cmd: str):
"""run
runs any command on the terminal
Args:
cmd (str): The command you want to run on the terminal
Returns:
str: the response as a string
"""
returned_output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return returned_output.decode("utf-8")
def __init__(self, *args, **kwargs) -> None:
self.args = args
self.kwargs = kwargs
self.params = "".join([each.__str__() for each in args])
self.result = ""
if not hasattr(self, "first_run"):
self.first_run = True
else:
self.first_run = False
self.run_command()
def __call__(self, *args, **kwargs):
self.run_command()
return self.result
def run_command(self):
if hasattr(self, "wait"):
self.has_wait = True
if self.first_run is True:
self.first_run = False
return
else:
self.has_wait = False
if hasattr(self, "iterable"):
if self.first_run is True:
self.first_run = False
return
try:
cmd = f"{self.name} {self.params}"
cmd = cmd.strip()
"""
# TODO - after doing all this. think i may have decided to go for 2 base commands instead
# one iterable and one normal. its still hidden from user as just a different inhereted command
# but would keep both simpler and can have more types. so will have to refactor all this again
# for now this behaves how i want despite the _new_ hack and double call on this command
"""
if self.has_wait is not True:
returned_output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
self.result = returned_output.decode("utf-8")
else:
self.result = "PING FAIL"
def kill_switch(proc):
proc.kill()
return
# try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
intId = window.setInterval(3000, kill_switch, proc)
self.result = proc.stdout.readlines()
window.clearInterval(intId)
# except subprocess.TimeoutExpired as e:
# self.result = returned_output.decode("utf-8")
# print('process ran too long')
except subprocess.CalledProcessError as e:
print(e.output)
self.result = e.output
raise TerminalException(e, self.result)
return
def __new__(cls, *args, **kwargs):
instance = super().__new__(cls)
instance.__init__(*args, **kwargs)
if hasattr(instance, "iterable"):
is_iterable = instance.iterable
if is_iterable:
return instance
return str(instance.result)
def __str__(self) -> str:
return str(self.result)
def __getitem__(self, index):
return self.result.splitlines()[index]
[docs]class cd(command):
"""
NOTE - 'cd' does not run on terminal
- cd is pointless as session opens and closes
- so is overridden to change dirs via pure python
"""
def run_command(self):
os.chdir(self.params)
# tested --
ls = type("ls", (command,), {"name": "ls", "iterable": True})
rm = type("rm", (command,), {"name": "rm"})
ln = type("ln", (command,), {"name": "ln"})
mkdir = type("mkdir", (command,), {"name": "mkdir"})
rmdir = type("rmdir", (command,), {"name": "rmdir"})
touch = type("touch", (command,), {"name": "touch"})
df = type("df", (command,), {"name": "df", "iterable": True})
du = type("du", (command,), {"name": "du", "iterable": True})
ps = type("ps", (command,), {"name": "ps", "iterable": True})
cat = type("cat", (command,), {"name": "cat", "iterable": True})
# --
mv = type("mv", (command,), {"name": "mv"})
cp = type("cp", (command,), {"name": "cp"})
rm = type("rm", (command,), {"name": "rm"})
chmod = type("chmod", (command,), {"name": "chmod"})
chown = type("chown", (command,), {"name": "chown"})
users = type("users", (command,), {"name": "users", "iterable": True})
useradd = type("useradd", (command,), {"name": "useradd"})
userdel = type("userdel", (command,), {"name": "userdel"})
groups = type("groups", (command,), {"name": "groups"})
groupadd = type("groupadd", (command,), {"name": "groupadd"})
groupdel = type("groupdel", (command,), {"name": "groupdel"})
uniq = type("uniq", (command,), {"name": "uniq"})
sort = type("sort", (command,), {"name": "sort"})
diff = type("diff", (command,), {"name": "diff"})
# cmp = type('cmp', (command,), {'name': 'cmp'})
ssh = type("ssh", (command,), {"name": "ssh"})
scp = type("scp", (command,), {"name": "scp"})
more = type("more", (command,), {"name": "more"})
less = type("less", (command,), {"name": "less"})
# vi = type('vi', (command,), {'name': 'vi'})
# emacs = type('emacs', (command,), {'name': 'emacs'})
head = type("head", (command,), {"name": "head", "iterable": True})
tail = type("tail", (command,), {"name": "tail", "iterable": True})
uptime = type("uptime", (command,), {"name": "uptime"})
bash = type("bash", (command,), {"name": "bash"})
shutdown = type("shutdown", (command,), {"name": "shutdown"})
reboot = type("reboot", (command,), {"name": "reboot"})
# open = type('open', (command,), {'name': 'open'})
killall = type("killall", (command,), {"name": "killall"})
mkfile = type("mkfile", (command,), {"name": "mkfile"})
ifconfig = type("ifconfig", (command,), {"name": "ifconfig", "iterable": True})
ipconfig = type("ipconfig", (command,), {"name": "ipconfig", "iterable": True})
finger = type("finger", (command,), {"name": "finger"})
passwd = type("passwd", (command,), {"name": "passwd"})
whoami = type("whoami", (command,), {"name": "whoami"})
# help = type('help', (command,), {'name': 'help'})
[docs]class history(command):
def run_command(self):
self.iterable = True
try:
# history is empty for non interactive sessions so read file
from os.path import expanduser, join
with open(join(expanduser("~"), ".bash_history"), "r") as f:
self.result = "".join(f.readlines())
except Exception as e:
print("failed to get history:", e)
self.result = ""
ping = type("ping", (command,), {"name": "ping", "wait": True, "iterable": True}) # < TODO - need to stream feedback
man = type("man", (command,), {"name": "man"})
find = type("find", (command,), {"name": "find"})
awk = type("awk", (command,), {"name": "awk"})
grep = type("grep", (command,), {"name": "grep"})
cut = type("cut", (command,), {"name": "cut"})
sed = type("sed", (command,), {"name": "sed"})
apt = type("apt", (command,), {"name": "apt"})
gunzip = type("gunzip", (command,), {"name": "gunzip"})
tar = type("tar", (command,), {"name": "tar"})
gzip = type("gzip", (command,), {"name": "gzip"})
cron = type("cron", (command,), {"name": "cron"})
crontab = type("crontab", (command,), {"name": "crontab"})
xargs = type("xargs", (command,), {"name": "xargs"})
nautilus = type("nautilus", (command,), {"name": "nautilus"}) # Linux only?
date = type("date", (command,), {"name": "date"})
cal = type("cal", (command,), {"name": "cal"})
bc = type("bc", (command,), {"name": "bc"})
rsync = type("rsync", (command,), {"name": "rsync"})
# https://github.com/agarrharr/awesome-cli-apps
# - NOTE - these ones may need installing if you haven't already
git = type("git", (command,), {"name": "git"})
wget = type("wget", (command,), {"name": "wget"})
nmap = type("nmap", (command,), {"name": "nmap"})
nohup = type("nohup", (command,), {"name": "nohup"})
python = type("python", (command,), {"name": "python"})
npm = type("npm", (command,), {"name": "npm"})
cowsay = type("cowsay", (command,), {"name": "cowsay"})
pip = type("pip", (command,), {"name": "pip"}) # TODO - change to 'python3 -m pip'? # TODO - both iterable and not
say = type("say", (command,), {"name": "say"}) # Mac only?
gcc = type("gcc", (command,), {"name": "gcc"})
jq = type("jq", (command,), {"name": "jq"})
curl = type("curl", (command,), {"name": "curl"})
ffmpeg = type("ffmpeg", (command,), {"name": "ffmpeg"})
convert = type("convert", (command,), {"name": "convert"}) # imagemagik
figlet = type("figlet", (command,), {"name": "figlet"})
banner = type("banner", (command,), {"name": "banner"})
# imagemagik
# asciiview
# toilet
# figlet
# youtube-dl = type('youtube-dl', (command,), {'name': 'youtube-dl'}) # TODO - illegal chars
# tree = type('tree', (command,), {'name': 'tree'})
# vim = type('vim', (command,), {'name': 'vim'})
# mail = type('mail', (command,), {'name': 'mail'})
# vncserver = type('vncserver', (command,), {'name': 'vncserver'})
# tmux
# https://en.wikipedia.org/wiki/List_of_Unix_commands
# admin = type('admin', (command,), {'name': 'admin'})
ar = type("ar", (command,), {"name": "ar"})
asa = type("asa", (command,), {"name": "asa"})
at = type("at", (command,), {"name": "at"})
basename = type("basename", (command,), {"name": "basename"})
batch = type("batch", (command,), {"name": "batch"})
bg = type("bg", (command,), {"name": "bg"})
cc = type("cc", (command,), {"name": "cc"})
cflow = type("cflow", (command,), {"name": "cflow"})
chgrp = type("chgrp", (command,), {"name": "chgrp"})
cksum = type("cksum", (command,), {"name": "cksum"})
comm = type("comm", (command,), {"name": "comm"})
compress = type("compress", (command,), {"name": "compress"})
csplit = type("csplit", (command,), {"name": "csplit"})
ctags = type("ctags", (command,), {"name": "ctags"})
cxref = type("cxref", (command,), {"name": "cxref"})
dd = type("dd", (command,), {"name": "dd"})
delta = type("delta", (command,), {"name": "delta"})
dirname = type("dirname", (command,), {"name": "dirname"})
ed = type("ed", (command,), {"name": "ed"})
env = type("env", (command,), {"name": "env"})
ex = type("ex", (command,), {"name": "ex"})
expand = type("expand", (command,), {"name": "expand"})
expr = type("expr", (command,), {"name": "expr"})
fc = type("fc", (command,), {"name": "fc"})
fg = type("fg", (command,), {"name": "fg"})
file = type("file", (command,), {"name": "file"})
fold = type("fold", (command,), {"name": "fold"})
fort77 = type("fort77", (command,), {"name": "fort77"})
fuser = type("fuser", (command,), {"name": "fuser"})
gencat = type("gencat", (command,), {"name": "gencat"})
get = type("get", (command,), {"name": "get"})
getconf = type("getconf", (command,), {"name": "getconf"})
getopts = type("getopts", (command,), {"name": "getopts"})
iconv = type("iconv", (command,), {"name": "iconv"})
# id = type('id', (command,), {'name': 'id'})
ipcrm = type("ipcrm", (command,), {"name": "ipcrm"})
ipcs = type("ipcs", (command,), {"name": "ipcs"})
join = type("join", (command,), {"name": "join"})
lex = type("lex", (command,), {"name": "lex"})
link = type("link", (command,), {"name": "link"})
locale = type("locale", (command,), {"name": "locale"})
localedef = type("localedef", (command,), {"name": "localedef"})
logger = type("logger", (command,), {"name": "logger"})
logname = type("logname", (command,), {"name": "logname"})
lp = type("lp", (command,), {"name": "lp"})
m4 = type("m4", (command,), {"name": "m4"})
mailx = type("mailx", (command,), {"name": "mailx"})
make = type("make", (command,), {"name": "make"})
mesg = type("mesg", (command,), {"name": "mesg"})
mkdir = type("mkdir", (command,), {"name": "mkdir"})
mkfifo = type("mkfifo", (command,), {"name": "mkfifo"})
more = type("more", (command,), {"name": "more"})
newgrp = type("newgrp", (command,), {"name": "newgrp"})
nice = type("nice", (command,), {"name": "nice"})
nl = type("nl", (command,), {"name": "nl"})
nm = type("nm", (command,), {"name": "nm"})
od = type("od", (command,), {"name": "od"})
paste = type("paste", (command,), {"name": "paste"})
patch = type("patch", (command,), {"name": "patch"})
pathchk = type("pathchk", (command,), {"name": "pathchk"})
pax = type("pax", (command,), {"name": "pax"})
pr = type("pr", (command,), {"name": "pr"})
prs = type("prs", (command,), {"name": "prs"})
qalter = type("qalter", (command,), {"name": "qalter"})
qdel = type("qdel", (command,), {"name": "qdel"})
qhold = type("qhold", (command,), {"name": "qhold"})
qmove = type("qmove", (command,), {"name": "qmove"})
qmsg = type("qmsg", (command,), {"name": "qmsg"})
qrerun = type("qrerun", (command,), {"name": "qrerun"})
qrls = type("qrls", (command,), {"name": "qrls"})
qselect = type("qselect", (command,), {"name": "qselect"})
qsig = type("qsig", (command,), {"name": "qsig"})
qstat = type("qstat", (command,), {"name": "qstat"})
qsub = type("qsub", (command,), {"name": "qsub"})
read = type("read", (command,), {"name": "read"})
renice = type("renice", (command,), {"name": "renice"})
rmdel = type("rmdel", (command,), {"name": "rmdel"})
sact = type("sact", (command,), {"name": "sact"})
sccs = type("sccs", (command,), {"name": "sccs"})
sed = type("sed", (command,), {"name": "sed"})
sh = type("sh", (command,), {"name": "sh"})
sleep = type("sleep", (command,), {"name": "sleep"})
split = type("split", (command,), {"name": "split"})
strings = type("strings", (command,), {"name": "strings"})
strip = type("strip", (command,), {"name": "strip"})
stty = type("stty", (command,), {"name": "stty"})
tabs = type("tabs", (command,), {"name": "tabs"})
talk = type("talk", (command,), {"name": "talk"})
tee = type("tee", (command,), {"name": "tee"})
test = type("test", (command,), {"name": "test"})
time = type("time", (command,), {"name": "time"})
tput = type("tput", (command,), {"name": "tput"})
tr = type("tr", (command,), {"name": "tr"})
true = type("true", (command,), {"name": "true"})
tsort = type("tsort", (command,), {"name": "tsort"})
tty = type("tty", (command,), {"name": "tty"})
uname = type("uname", (command,), {"name": "uname"})
uncompress = type("uncompress", (command,), {"name": "uncompress"})
unexpand = type("unexpand", (command,), {"name": "unexpand"})
unget = type("unget", (command,), {"name": "unget"})
unlink = type("unlink", (command,), {"name": "unlink"})
uucp = type("uucp", (command,), {"name": "uucp"})
uudecode = type("uudecode", (command,), {"name": "uudecode"})
uuencode = type("uuencode", (command,), {"name": "uuencode"})
uustat = type("uustat", (command,), {"name": "uustat"})
uux = type("uux", (command,), {"name": "uux"})
val = type("val", (command,), {"name": "val"})
wc = type("wc", (command,), {"name": "wc"}) # < TODO - stream. plus figure out piping
what = type("what", (command,), {"name": "what"})
who = type("who", (command,), {"name": "who"})
write = type("write", (command,), {"name": "write"})
yacc = type("yacc", (command,), {"name": "yacc"})
zcat = type("zcat", (command,), {"name": "zcat"})
# bash builtins
alias = type("alias", (command,), {"name": "alias"})
bg = type("bg", (command,), {"name": "bg"})
bind = type("bind", (command,), {"name": "bind"})
# break = type('break', (command,), {'name': 'break'})
builtin = type("builtin", (command,), {"name": "builtin"})
caller = type("caller", (command,), {"name": "caller"})
# command = type('command', (command,), {'name': 'command'})
compgen = type("compgen", (command,), {"name": "compgen"})
complete = type("complete", (command,), {"name": "complete"})
compopt = type("compopt", (command,), {"name": "compopt"})
# continue = type('continue', (command,), {'name': 'continue'})
declare = type("declare", (command,), {"name": "declare"})
dirs = type("dirs", (command,), {"name": "dirs"})
disown = type("disown", (command,), {"name": "disown"})
echo = type("echo", (command,), {"name": "echo"})
enable = type("enable", (command,), {"name": "enable"})
# eval = type('eval', (command,), {'name': 'eval'})
# exec = type('exec', (command,), {'name': 'exec'})
exit = type("exit", (command,), {"name": "exit"})
export = type("export", (command,), {"name": "export"})
# false = type('false', (command,), {'name': 'false'})
fc = type("fc", (command,), {"name": "fc"})
fg = type("fg", (command,), {"name": "fg"})
getopts = type("getopts", (command,), {"name": "getopts"})
# hash = type('hash', (command,), {'name': 'hash'})
# help = type('help', (command,), {'name': 'help'})
jobs = type("jobs", (command,), {"name": "jobs"})
kill = type("kill", (command,), {"name": "kill"})
let = type("let", (command,), {"name": "let"})
local = type("local", (command,), {"name": "local"})
logout = type("logout", (command,), {"name": "logout"})
mapfile = type("mapfile", (command,), {"name": "mapfile"})
popd = type("popd", (command,), {"name": "popd"})
printf = type("printf", (command,), {"name": "printf"})
pushd = type("pushd", (command,), {"name": "pushd"})
pwd = type("pwd", (command,), {"name": "pwd"})
read = type("read", (command,), {"name": "read"})
readarray = type("readarray", (command,), {"name": "readarray"})
readonly = type("readonly", (command,), {"name": "readonly"})
# return = type('return', (command,), {'name': 'return'})
# set = type('set', (command,), {'name': 'set'})
shift = type("shift", (command,), {"name": "shift"})
shopt = type("shopt", (command,), {"name": "shopt"})
source = type("source", (command,), {"name": "source"})
suspend = type("suspend", (command,), {"name": "suspend"})
# test = type('test', (command,), {'name': 'test'})
times = type("times", (command,), {"name": "times"})
trap = type("trap", (command,), {"name": "trap"})
# true = type('true', (command,), {'name': 'true'})
# type = type('type', (command,), {'name': 'type'})
typeset = type("typeset", (command,), {"name": "typeset"})
ulimit = type("ulimit", (command,), {"name": "ulimit"})
umask = type("umask", (command,), {"name": "umask"})
unalias = type("unalias", (command,), {"name": "unalias"})
unset = type("unset", (command,), {"name": "unset"})
wait = type("wait", (command,), {"name": "wait"})
# https://ss64.com/bash/
# PIPE etc?