Truncated history of git repo
This commit is contained in:
commit
5cbeb519b0
|
|
@ -0,0 +1,6 @@
|
|||
git/gitconfig
|
||||
neovim/.plug/
|
||||
vim/autoload/plug.vim.old
|
||||
*.zwc
|
||||
.uuid
|
||||
.netrwhist
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# dotfiles
|
||||
|
||||
git clone https://github.com/jcosmao/dotfiles.git
|
||||
cd dotfiles && ./install.sh
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
xrdb .Xresources
|
||||
eval `ssh-agent -s`
|
||||
exec dbus-launch i3
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Section "InputClass"
|
||||
Identifier "system-keyboard"
|
||||
MatchIsKeyboard "on"
|
||||
Option "XkbLayout" "us"
|
||||
Option "XkbVariant" "altgr-intl"
|
||||
Option "XkbModel" "pc105+inet"
|
||||
Option "XkbOptions" "terminate:ctrl_alt_bksp"
|
||||
EndSection
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
Section "InputClass"
|
||||
Identifier "Force Clickpad Config"
|
||||
MatchDriver "synaptics"
|
||||
Option "ClickPad" "true"
|
||||
Option "EmulateMidButtonTime" "0"
|
||||
Option "SoftButtonAreas" "50% 0 82% 0 0 0 0 0"
|
||||
Option "SecondarySoftButtonAreas" "58% 0 0 15% 42% 58% 0 15%"
|
||||
Option "TapButton1" "1"
|
||||
Option "TapButton2" "3"
|
||||
Option "TapButton3" "2"
|
||||
Option "VertEdgeScroll" "off"
|
||||
Option "HorizEdgeScroll" "off"
|
||||
Option "VertTwoFingerScroll" "on"
|
||||
Option "HorizTwoFingerScroll" "on"
|
||||
Option "CircularScrolling" "on"
|
||||
Option "CircScrollTrigger" "2"
|
||||
Option "EmulateTwoFingerMinZ" "0"
|
||||
Option "PalmDetect" "1"
|
||||
Option "PalmMinWidth" "8"
|
||||
Option "PalmMinZ" "100"
|
||||
EndSection
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
bat https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb
|
||||
kubecolor (debian 12) http://ftp.debian.org/debian/pool/main/k/kubecolor/kubecolor_0.0.20-2+b6_amd64.deb
|
||||
ripgrep https://github.com/BurntSushi/ripgrep/releases/latest
|
||||
fd https://github.com/sharkdp/fd/releases/latest
|
||||
ctgags compiled from https://github.com/universal-ctags/ctags.git
|
||||
fzf debian 11
|
||||
rofi ubuntu 22.04
|
||||
stern https://github.com/stern/stern/releases/tag/v1.25.0
|
||||
jq https://github.com/jqlang/jq/releases/tag/jq-1.7
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,459 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# forked from: https://github.com/gaelL/openstack-log-colorizer
|
||||
#
|
||||
# Author: Gaël Lambert (gaelL) <gael.lambert@netwiki.fr>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Filter and color Openstack log files from stdin
|
||||
|
||||
--
|
||||
It support log files:
|
||||
- openstack services with default log format (work also using journalctl, stern)
|
||||
* journalctl: journalctl --no-hostname -o short-iso -u 'devstack@*'
|
||||
- openvswitch
|
||||
- rabbitmq
|
||||
- apache
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import re
|
||||
import argparse
|
||||
|
||||
|
||||
LOG_LEVEL = {
|
||||
'critical': 50,
|
||||
'emer': 50,
|
||||
'error': 40,
|
||||
'err': 40,
|
||||
'warning': 30,
|
||||
'warn': 30,
|
||||
'wrn': 30,
|
||||
'info': 20,
|
||||
'inf': 20,
|
||||
'debug': 10,
|
||||
'dbg': 10,
|
||||
'notset': 100,
|
||||
}
|
||||
|
||||
PARSER = argparse.ArgumentParser(description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
PARSER.add_argument("-l", "--level",
|
||||
help="Set log levels you want display",
|
||||
metavar='level',
|
||||
choices=LOG_LEVEL.keys(),
|
||||
type=str)
|
||||
PARSER.add_argument("-e", "--exclude",
|
||||
help="Set log levels you want exclude",
|
||||
metavar='level',
|
||||
choices=LOG_LEVEL.keys(),
|
||||
type=str,
|
||||
nargs='+')
|
||||
PARSER.add_argument("-i", "--include",
|
||||
help="Set log levels you only want display",
|
||||
metavar='level',
|
||||
choices=LOG_LEVEL.keys(),
|
||||
type=str,
|
||||
nargs='+')
|
||||
ARGS = PARSER.parse_args()
|
||||
|
||||
|
||||
class colors:
|
||||
grey = '\033[1;30m'
|
||||
red = '\033[1;31m'
|
||||
green = '\033[1;32m'
|
||||
yellow = '\033[1;33m'
|
||||
blue = '\033[1;34m'
|
||||
magenta = '\033[1;35m'
|
||||
cyan = '\033[1;36m'
|
||||
white = '\033[0;37m'
|
||||
end = '\033[1;m'
|
||||
|
||||
|
||||
def grey(text):
|
||||
return '%s%s%s' % (colors.grey, text, colors.end)
|
||||
|
||||
|
||||
def red(text):
|
||||
return '%s%s%s' % (colors.red, text, colors.end)
|
||||
|
||||
|
||||
def green(text):
|
||||
return '%s%s%s' % (colors.green, text, colors.end)
|
||||
|
||||
|
||||
def yellow(text):
|
||||
return '%s%s%s' % (colors.yellow, text, colors.end)
|
||||
|
||||
|
||||
def blue(text):
|
||||
return '%s%s%s' % (colors.blue, text, colors.end)
|
||||
|
||||
|
||||
def magenta(text):
|
||||
return '%s%s%s' % (colors.magenta, text, colors.end)
|
||||
|
||||
|
||||
def cyan(text):
|
||||
return '%s%s%s' % (colors.cyan, text, colors.end)
|
||||
|
||||
|
||||
def white(text):
|
||||
return '%s%s%s' % (colors.white, text, colors.end)
|
||||
|
||||
|
||||
def colored_level(level):
|
||||
"Return level text with selected color tag"
|
||||
level = level.upper()
|
||||
if level in ['TRACE', 'SEC']:
|
||||
return magenta(level)
|
||||
elif level in ['DEBUG', 'DBG', 'INFO', 'INF']:
|
||||
return green(level)
|
||||
elif level in ['WARNING', 'WRN', 'WARN', '???']:
|
||||
return yellow(level)
|
||||
elif level in ['CRITICAL', 'ERROR', 'ERR', 'EMER']:
|
||||
return red(level)
|
||||
else:
|
||||
return white(level)
|
||||
|
||||
|
||||
def parse_line(line):
|
||||
"Parse line and return dict of each elements"
|
||||
# Line example : Openstack
|
||||
# 2014-08-14 18:43:58.950 4092 INFO neutron.plugins.openvswitch.agent.ovs_neutron_agent [-]
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r'([0-9]{4}-[0-9]+-[0-9]+) ' # date
|
||||
r'([0-9]+:[0-9]+:[0-9]+\.[0-9]+) ' # time
|
||||
r'([0-9]+):? ' # process
|
||||
r'([A-Z]+) ' # level
|
||||
r'([^ ]+)* ' # name
|
||||
r"(\[(?!'Traceback)[^\]]+\])*\s*" # context
|
||||
r'(.+)*' # text
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
return {
|
||||
'header': "" if not result.group(1) else result.group(1),
|
||||
'date': result.group(2),
|
||||
'time': result.group(3),
|
||||
'process': result.group(4),
|
||||
'level': result.group(5),
|
||||
'name': "" if not result.group(6) else result.group(6),
|
||||
'req': "" if not result.group(7) else result.group(7),
|
||||
'text': "" if not result.group(8) else result.group(8),
|
||||
'_type': 'openstack',
|
||||
}
|
||||
|
||||
# journalctl --no-hostname -o short-iso -f -u 'devstack@*'
|
||||
# 2024-03-20T13:27:44+0000 devstack@keystone.service[74735]: INFO neutron.plugins.openvswitch.agent.ovs_neutron_agent [-]
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r'([0-9]{4}-[0-9]+-[0-9]+)T' # date
|
||||
r'([0-9]+:[0-9]+:[0-9]+\+[0-9]+) ' # time
|
||||
r'([^\[]+)\[([0-9]+)\]: ' # unit process
|
||||
r'([A-Z]+) ' # level
|
||||
r'([^ ]+)* ' # name
|
||||
r"(\[(?!'Traceback)[^\]]+\])*\s*" # context
|
||||
r'(.+)*' # text
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
h = ""
|
||||
if result.group(1):
|
||||
h = result.group(1)
|
||||
# it's unit name
|
||||
elif result.group(4):
|
||||
h = f"{result.group(4)} "
|
||||
|
||||
return {
|
||||
'header': h,
|
||||
'date': result.group(2),
|
||||
'time': result.group(3),
|
||||
'process': result.group(5),
|
||||
'level': result.group(6),
|
||||
'name': "" if not result.group(7) else result.group(7),
|
||||
'req': "" if not result.group(8) else result.group(8),
|
||||
'text': "" if not result.group(9) else result.group(9),
|
||||
'_type': 'openstack',
|
||||
}
|
||||
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r"(\['Traceback.*)"
|
||||
)
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
return {
|
||||
'header': "" if not result.group(1) else result.group(1),
|
||||
'date': "",
|
||||
'time': "",
|
||||
'process': "",
|
||||
'level': "TRACE",
|
||||
'name': "" ,
|
||||
'req': "",
|
||||
'text': "" if not result.group(2) else result.group(2),
|
||||
'_type': 'openstack',
|
||||
}
|
||||
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r'([0-9]{4}-[0-9]+-[0-9]+) ' # date
|
||||
r'([0-9]+:[0-9]+:[0-9]+) ' # time
|
||||
r'(.+)'
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
key_val = {}
|
||||
text = result.group(4)
|
||||
keys = re.findall(r"[^ ]+:", text)
|
||||
for i in range(0, len(keys)):
|
||||
if i == len(keys) - 1:
|
||||
next_key = ""
|
||||
else:
|
||||
next_key = keys[i+1]
|
||||
|
||||
match = re.match(rf".*{keys[i]} (.*){next_key}.*", text)
|
||||
if match:
|
||||
key_val[keys[i]] = match.group(1)
|
||||
|
||||
return {
|
||||
'header': "" if not result.group(1) else result.group(1),
|
||||
'date': result.group(2),
|
||||
'time': result.group(3),
|
||||
'key_val': key_val,
|
||||
'_type': 'apache',
|
||||
}
|
||||
|
||||
# rabbit
|
||||
# 2023-07-30 12:39:41.230254+00:00 [error]
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r'([0-9]{4}-[0-9]+-[0-9]+) ' # date
|
||||
r'([0-9]+:[0-9]+:[0-9]+\.[0-9]+[^ ]+) ' # time
|
||||
r'\[([a-z\?]+)\] ' # level
|
||||
r'(<[^>]+>) ' # <0.9417.870>
|
||||
r'(.+)*'
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
return {
|
||||
'header': "" if not result.group(1) else result.group(1),
|
||||
'date': result.group(2),
|
||||
'time': result.group(3),
|
||||
'level': result.group(4),
|
||||
'pid': result.group(5),
|
||||
'text': result.group(6),
|
||||
'_type': 'rabbit',
|
||||
}
|
||||
|
||||
# Line example : ovs.log
|
||||
# 2014-11-21T06:25:09.549Z|00012|vlog|INFO|opened log file /var/log/op...
|
||||
regex = (
|
||||
r'(.*)'
|
||||
r'([0-9]{4}-[0-9]+-[0-9]+)T' # date
|
||||
r'([0-9]+:[0-9]+:[0-9]+\.[0-9]+)Z\|' # time
|
||||
r'([0-9]+)\|' # serial
|
||||
r'([^\|]+)\|' # name
|
||||
r'([^\|]+)\|' # level
|
||||
r'(.+)'
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
return {
|
||||
'header': "" if not result.group(1) else result.group(1),
|
||||
'date': result.group(2),
|
||||
'time': result.group(3),
|
||||
'serial': result.group(4),
|
||||
'name': result.group(5),
|
||||
'level': result.group(6),
|
||||
'text': result.group(7),
|
||||
'_type': 'ovs',
|
||||
}
|
||||
|
||||
regex = (
|
||||
r'([^ ]+ [^ ]+)'
|
||||
r'(.+)*'
|
||||
)
|
||||
|
||||
result = re.match(regex, line)
|
||||
if result is not None:
|
||||
return {
|
||||
'header': '' if not result.group(1) else result.group(1),
|
||||
'text': '' if not result.group(2) else result.group(2),
|
||||
'_type': None,
|
||||
}
|
||||
|
||||
return {'header': '', 'text': line, '_type': None}
|
||||
|
||||
|
||||
def colorize(line):
|
||||
"Apply color tag on line"
|
||||
|
||||
if line.get('_type') == 'openstack':
|
||||
if line.get('level') in ['TRACE', 'ERROR']:
|
||||
if "['Traceback" in line.get('text'):
|
||||
line['text'] = line['text'].replace('\\n', '\n')
|
||||
|
||||
if line.get('level') == 'TRACE':
|
||||
colored_text = grey(line['text'])
|
||||
else:
|
||||
colored_text = white(line['text'])
|
||||
|
||||
return '%s%s %s %s %s %s %s %s' % (
|
||||
magenta(line['header']),
|
||||
grey(line['date']),
|
||||
grey(line['time']),
|
||||
grey(line['process']),
|
||||
colored_level(line['level']),
|
||||
blue(line['name']),
|
||||
grey(line['req']),
|
||||
colored_text
|
||||
)
|
||||
|
||||
elif line.get('_type') == 'ovs':
|
||||
return '%s%s %s %s %s %s %s' % (
|
||||
magenta(line['header']),
|
||||
grey(line['date']),
|
||||
grey(line['time']),
|
||||
grey(line['serial']),
|
||||
blue(line['name']),
|
||||
colored_level(line['level']),
|
||||
white(line['text'])
|
||||
)
|
||||
|
||||
elif line.get('_type') == 'rabbit':
|
||||
return '%s%s %s %s %s %s' % (
|
||||
magenta(line['header']),
|
||||
grey(line['date']),
|
||||
grey(line['time']),
|
||||
colored_level(line['level']),
|
||||
blue(line['pid']),
|
||||
white(line['text'])
|
||||
)
|
||||
|
||||
elif line.get('_type') == 'apache':
|
||||
formatted = '%s%s %s' % (
|
||||
magenta(line['header']),
|
||||
grey(line['date']),
|
||||
grey(line['time']),
|
||||
)
|
||||
|
||||
for k, v in line['key_val'].items():
|
||||
val = white(v)
|
||||
try:
|
||||
if k == "status:" and int(v) >= 500:
|
||||
val = red(v)
|
||||
elif k == "status:" and int(v) >= 400:
|
||||
val = yellow(v)
|
||||
elif k == "time:" and float(v) >= 1000:
|
||||
val = red(v)
|
||||
except Exception:
|
||||
pass
|
||||
formatted = f"{formatted} {blue(k)} {val}"
|
||||
|
||||
return formatted
|
||||
|
||||
else:
|
||||
return '%s %s' % (magenta(line['header']), line.get('text'))
|
||||
|
||||
|
||||
def check_args():
|
||||
# Just allow one arg
|
||||
num_args = sum(1 for i in [ARGS.level, ARGS.exclude, ARGS.include] if i)
|
||||
if num_args > 1:
|
||||
print('Args conflicts select just one arg')
|
||||
PARSER.print_help()
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def level_filter(line):
|
||||
"Return true if line must be filtered. Never filter line without level"
|
||||
level = ARGS.level.lower()
|
||||
line_level = line.get('level', 'notset').lower()
|
||||
if LOG_LEVEL.get(line_level, 100) < LOG_LEVEL.get(level, 0):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def include_filter(line):
|
||||
"Return true if line must be filtered. Never filter line without level"
|
||||
includes = [i.lower() for i in ARGS.include]
|
||||
line_level = line.get('level', 'notset').lower()
|
||||
if line_level == 'notset':
|
||||
return False
|
||||
elif line_level in includes:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def exclude_filter(line):
|
||||
"Return true if line must be filtered. Never filter line without level"
|
||||
excludes = [e.lower() for e in ARGS.exclude]
|
||||
line_level = line.get('level', 'notset').lower()
|
||||
if line_level in excludes:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def line_is_filtered(line):
|
||||
"Skip the line ?"
|
||||
if ARGS.level:
|
||||
return level_filter(line)
|
||||
elif ARGS.include:
|
||||
return include_filter(line)
|
||||
elif ARGS.exclude:
|
||||
return exclude_filter(line)
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Read each line in stdin
|
||||
if not check_args():
|
||||
sys.exit(1)
|
||||
|
||||
while 1:
|
||||
try:
|
||||
line = sys.stdin.readline()
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
|
||||
if not line:
|
||||
break
|
||||
|
||||
try:
|
||||
# get parsed line
|
||||
parsed_line = parse_line(line.rstrip('\n'))
|
||||
except Exception:
|
||||
parsed_line = {'header': '', 'text': line.rstrip('\n'), '_type': None}
|
||||
|
||||
# Skip line if filtred (never skip line without log level)
|
||||
if line_is_filtered(parsed_line):
|
||||
continue
|
||||
|
||||
# Print parsed and colored line
|
||||
print(colorize(parsed_line))
|
||||
|
|
@ -0,0 +1,817 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#ToDo:
|
||||
# Remote window title is wrong
|
||||
# Remote audio: delay is still a bit high (less than 100ms)
|
||||
# Understand why audio starts with a long delay unless
|
||||
# we keep playing a stream in background (as we now do)
|
||||
# * allow tho choose video player by command line
|
||||
|
||||
#Requirements:
|
||||
#Local+Remote: ffmpeg,openssh,netevent-git
|
||||
#Local: wmctrl, optional: mpv + taskset from util-linux to get even lower latency but with more cpu use.
|
||||
#Remote: xdpyinfo,pulseaudio
|
||||
#read/write access to input devices on local and remote system (input group) (sudo gpasswd --add username input)
|
||||
|
||||
#Remote host
|
||||
RHOST="" # Remote ip or hostname
|
||||
RPORT="22" # Remote ssh port to connect to
|
||||
RUSER="" # The user on the remote side running the real X server
|
||||
RDISPLAY="0.0" # The remote display (ex: 0.0)
|
||||
EVDFILE="$HOME/.config/ssh-rdp.input.evd.config" #Holds the name of the forwarded evdev device
|
||||
KBDFILE="$HOME/.config/ssh-rdp.input.kbd.config" #Holds the name of the forwarded keyboard evdev device
|
||||
HKFILE="$HOME/.config/ssh-rdp.input.hk.config" #where the keypress codes to switch fullscreen and forward reside
|
||||
|
||||
#Encoding:
|
||||
AUDIO_CAPTURE_SOURCE="AUTO" # "pulseaudio name like alsa_output.pci-0000_00_1b.0.analog-stereo.monitor" or "guess"
|
||||
FPS=60 # frames per second of the stream
|
||||
RES="AUTO" # "ex: RES="1280x1024" or RES="AUTO".
|
||||
# If wrong, video grab will not work.
|
||||
OFFSET="+0,0" # ex: OFFSET="" or OFFSET="+10,+40".
|
||||
# If wrong, video grab will not work.
|
||||
|
||||
#The "null,null" video filters will be changed to -vf scale by sed later on if prescale is requested
|
||||
#VIDEO_ENC_CPU="-threads 1 -vcodec libx264 -thread_type slice -slices 1 -level 32 -preset ultrafast -tune zerolatency -intra-refresh 1 -x264opts vbv-bufsize=1:slice-max-size=1500:keyint=$FPS:sliced_threads=1 -pix_fmt nv12 -vf 'null,null'"
|
||||
VIDEO_ENC_CPU="-threads 1 -vcodec libx264 -thread_type slice -slices 1 -level 32 -preset ultrafast -tune zerolatency -intra-refresh 1 -x264opts keyint=$FPS:sliced_threads=1 -pix_fmt nv12 -vf 'null,null'"
|
||||
VIDEO_ENC_CPU_RGB="-threads 1 -vcodec libx264rgb -profile:v high444 -thread_type slice -slices 1 -level 32 -preset ultrafast -tune zerolatency -intra-refresh 1 -x264opts keyint=$FPS:sliced_threads=1 -pix_fmt bgr24 -vf 'null,null'"
|
||||
VIDEO_ENC_NVGPU="-threads 1 -c:v h264_nvenc -preset llhq -delay 0 -zerolatency 1 -vf 'null,null'"
|
||||
VIDEO_ENC_NVGPU_HEVC="-threads 1 -c:v hevc_nvenc -preset llhq -delay 0 -zerolatency 1 -vf 'null,null'"
|
||||
VIDEO_ENC_AMDGPU="-threads 1 -vaapi_device /dev/dri/renderD128 -c:v h264_vaapi -bf 0 -vf 'null,null,hwupload,scale_vaapi=format=nv12'"
|
||||
VIDEO_ENC_AMDGPU_HEVC="-threads 1 -vaapi_device /dev/dri/renderD128 -c:v hevc_vaapi -bf 0 -vf 'null,null,hwupload,scale_vaapi=format=nv12'"
|
||||
VIDEO_ENC_INTELGPU="-threads 1 -vaapi_device /dev/dri/renderD128 -c:v h264_vaapi -bf 0 -vf 'null,null,hwupload,scale_vaapi=format=nv12'"
|
||||
#VIDEO_ENC_INTELGPU="-threads 1 -vaapi_device /dev/dri/renderD128 -c:v h264_vaapi -bf 0 -vf 'null,null,format=nv12,hwupload'"
|
||||
|
||||
AUDIO_ENC_OPUS="-acodec libopus -vbr off -application lowdelay -frame_duration 10" #opus, low delay great quality
|
||||
AUDIO_ENC_PCM="-acodec pcm_s16le " #pcm, low delay, best quality
|
||||
|
||||
VIDEOENC="cpu"
|
||||
AUDIOENC="opus"
|
||||
|
||||
VIDEO_BITRATE_MAX="5000" #kbps (or AUTO)
|
||||
VIDEO_BITRATE_MAX_SCALE="80" # When VIDEO_BITRATE_MAX is set to "AUTO", only use this percentual of it.
|
||||
AUDIO_BITRATE=128 #kbps
|
||||
|
||||
AUDIO_DELAY_COMPENSATION="4000" #The higher the value, the lower the audio delay.
|
||||
#Setting this too high will likely produce crackling sound.
|
||||
#Try in range 0-8000
|
||||
|
||||
#Prescale desktop before sending?
|
||||
PRESCALE="" # eg: "" or something like "1280x720"
|
||||
|
||||
#Prescaling quality see https://ffmpeg.org/ffmpeg-scaler.html for possible values
|
||||
SCALE_FLT="fast_bilinear" #bilinear,bicubic,lanczos,spline...
|
||||
|
||||
#Remote window title
|
||||
#WTITLE="$RUSER@$RHOST""$RDISPLAY"
|
||||
WTITLE="ssh-rdp""-"\["$$"\]
|
||||
|
||||
# Misc
|
||||
SSH_CIPHER="" #Optionally, force an ssh cipher to be used
|
||||
#SSH_CIPHER="aes256-gcm@openssh.com"
|
||||
|
||||
|
||||
# ### User config ends here ### #
|
||||
|
||||
ICFILE_RUNTIME=~/.config/ssh-rdp.input.out.config
|
||||
|
||||
print_error() { echo -e "\e[1m\e[91m[EE] $1\e[0m" ;};
|
||||
print_warning() { echo -e "\e[1m\e[93m[WW] $1\e[0m" ;};
|
||||
print_notice() { echo -e "\e[1m[!!] $1\e[0m" ;};
|
||||
print_ok() { echo -e "\e[1m\e[92m[OK] $1\e[0m" ;};
|
||||
print_pending() { echo -e "\e[1m\e[94m[..] $1\e[0m" ;};
|
||||
|
||||
ask_continue_or_exit(){
|
||||
while true; do
|
||||
read -p "$(print_warning "Do you want to continue anyway (not recommended) (y/n) ? ")" yn
|
||||
case $yn in
|
||||
[Yy]* ) ERROR=0; break;;
|
||||
[Nn]* ) ERROR=1; break;;
|
||||
* ) print_error "Please answer y or n.";;
|
||||
esac
|
||||
done
|
||||
if [ "$ERROR" = "1" ] ; then
|
||||
print_error "Cannot continue."
|
||||
exit
|
||||
else
|
||||
print_warning "Proceeding anyway..."
|
||||
fi
|
||||
}
|
||||
|
||||
generate_ICFILE_from_names() {
|
||||
#Also, exits from the script if no keyboard is found
|
||||
I_IFS="$IFS"
|
||||
IFS=$'\n' ;
|
||||
ICFILE_REJ=~/.config/ssh-rdp.input.rej.txt
|
||||
|
||||
rm $ICFILE_RUNTIME $ICFILE_REJ &>/dev/null
|
||||
ERROR="0"
|
||||
print_pending "Checking input devices..."
|
||||
for device_name in $(<$EVDFILE) ; do
|
||||
evdev_devices=$(events_from_name "$device_name")
|
||||
if [ "$evdev_devices" = "" ] ; then
|
||||
print_warning "Device unavailable : $device_name"
|
||||
else
|
||||
print_ok "Device ready : $device_name"
|
||||
for evdevice in $evdev_devices ; do
|
||||
echo " add event device for $device_name: $evdevice"
|
||||
echo -n $evdevice" " >> "$ICFILE_RUNTIME"
|
||||
done
|
||||
fi
|
||||
done
|
||||
IFS="$I_IFS"
|
||||
print_pending "Reading hotkey file $HKFILE"
|
||||
read GRAB_HOTKEY FULLSCREENSWITCH_HOTKEY <<< $(<$HKFILE)
|
||||
print_ok "GRAB_HOTKEY=$GRAB_HOTKEY"
|
||||
print_ok "FULLSCREENSWITCH_HOTKEY=$FULLSCREENSWITCH_HOTKEY"
|
||||
}
|
||||
|
||||
function get_input_event_device(){
|
||||
#Show the first event device that "emits some input"
|
||||
cd /dev/input/
|
||||
tmpfile=/tmp/$$devices$$.txt
|
||||
rm $tmpfile &>/dev/null
|
||||
touch $tmpfile
|
||||
timeout=120
|
||||
|
||||
#Listen for events
|
||||
pids=("")
|
||||
sleep 0.1
|
||||
for d in event* ; do
|
||||
timeout $timeout sh -c "grep . $d -m 1 -c -H |cut -d ":" -f 1 > $tmpfile" &
|
||||
pids+=("$!")
|
||||
done
|
||||
|
||||
#Wait for one event to come
|
||||
while ! [ -s $tmpfile ] ; do
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
#Show the event device
|
||||
cat $tmpfile
|
||||
|
||||
#Cleanup
|
||||
for pid in ${pids[@]} ; do
|
||||
kill $pid &>/dev/null
|
||||
done
|
||||
rm $tmpfile
|
||||
}
|
||||
|
||||
name_from_event(){
|
||||
#es: name_from_event event3
|
||||
#Logitech G203 Prodigy Gaming Mouse
|
||||
grep 'Name=\|Handlers' /proc/bus/input/devices|grep -w -B1 "$1"|head -n 1|cut -d \" -f 2
|
||||
}
|
||||
|
||||
events_from_name(){
|
||||
#es: vents_from_name Logitech G203 Prodigy Gaming Mouse
|
||||
#event13
|
||||
#event2
|
||||
grep 'Name=\|Handlers' /proc/bus/input/devices|grep -A1 "$1"|cut -d "=" -f 2 |grep -o '[^ ]*event[^ ]*'
|
||||
}
|
||||
|
||||
check_local_input_group(){
|
||||
if ! id -nG $(id -u)|grep -qw input ; then
|
||||
echo
|
||||
print_warning "local user is not in the input group,"
|
||||
print_warning "but /dev/input/* access is required to forward input devices."
|
||||
ask_continue_or_exit
|
||||
fi
|
||||
}
|
||||
|
||||
check_remote_uinput_access(){
|
||||
UINPUT=/dev/uinput # /dev/uinput
|
||||
$SSH_EXEC "test -e $UINPUT" || E="noexist"
|
||||
if [ "$E" = "noexist" ] ; then
|
||||
echo
|
||||
print_warning "Remote system has no $UINPUT"
|
||||
print_warning "which is needed to forward input devices."
|
||||
print_warning "Please, configure it to load the uinput module or build uinput into the kernel."
|
||||
ask_continue_or_exit
|
||||
else #/dev/uinput was found
|
||||
$SSH_EXEC "test -w $UINPUT" || E="noaccess"
|
||||
$SSH_EXEC "test -r $UINPUT" || E="noaccess"
|
||||
if [ "$E" = "noaccess" ] ; then
|
||||
echo
|
||||
print_warning "Remote user is missing R/W access to $UINPUT"
|
||||
print_warning "which is needed to forward input devices."
|
||||
ask_continue_or_exit
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
create_input_files() {
|
||||
check_local_input_group
|
||||
tmpfile=/tmp/$$devices$$.txt
|
||||
sleep 0.1
|
||||
rm $EVDFILE &>/dev/null
|
||||
|
||||
#Ask user to generate input to auto select input devices to forward
|
||||
echo
|
||||
print_pending "Please, press a key on the keyboard you want to forward."
|
||||
KBDDEV=$(get_input_event_device)
|
||||
KBDNAME=$(name_from_event $KBDDEV)
|
||||
echo -ne "\r"
|
||||
print_ok "Got keyboard: $KBDNAME on $KBDDEV.\n"
|
||||
name_from_event $KBDDEV > $KBDFILE
|
||||
echo $KBDNAME > $EVDFILE
|
||||
|
||||
ANOTHER_DEVICE=1
|
||||
while [ $ANOTHER_DEVICE == 1 ]; do
|
||||
while true; do
|
||||
read -t 0.5 -N 255 #empty input buffer
|
||||
read -p "$(print_warning "Do you want to forward other devices? (y/n) ? ")" yn
|
||||
case $yn in
|
||||
[Yy]* )
|
||||
print_pending "Please, generate input with the device you want to forward."
|
||||
EVDEV=$(get_input_event_device)
|
||||
EVDEV_NAME=$(name_from_event $EVDEV)
|
||||
if grep "$EVDEV_NAME" $EVDFILE >/dev/null ; then
|
||||
print_error "Not adding $EVDEV_NAME because it is already in the forward list."
|
||||
else
|
||||
print_ok "Got $EVDEV_NAME on $EVDEV"
|
||||
echo -ne "\r"
|
||||
echo $EVDEV_NAME >> $EVDFILE
|
||||
fi
|
||||
echo
|
||||
;;
|
||||
[Nn]* )
|
||||
ANOTHER_DEVICE=0; break;;
|
||||
* )
|
||||
print_error "Please answer y or n.";;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
# create_hk_file
|
||||
# uses netevent to generate a file containing the key codes
|
||||
# to switch fullscreen and forward devices
|
||||
cd /dev/input
|
||||
rm $HKFILE &>/dev/null
|
||||
sleep 0.1
|
||||
echo ; print_pending "Press the key to that will be used to forward/unforward input devices"
|
||||
GRAB_HOTKEY=$(netevent show $KBDDEV 3 -g | grep KEY |cut -d ":" -f 2) ; print_ok "got:$GRAB_HOTKEY"
|
||||
sleep 0.5
|
||||
echo ; print_pending "Now press the key that will be used to switch fullscreen state"
|
||||
FULLSCREENSWITCH_HOTKEY=$(netevent show $KBDDEV 3 -g | grep KEY |cut -d ":" -f 2) ; print_ok "got:$FULLSCREENSWITCH_HOTKEY"
|
||||
echo $GRAB_HOTKEY $FULLSCREENSWITCH_HOTKEY > $HKFILE
|
||||
|
||||
read GRAB_HOTKEY FULLSCREENSWITCH_HOTKEY <<< $(<$HKFILE)
|
||||
echo
|
||||
echo GRAB_HOTKEY=$GRAB_HOTKEY
|
||||
echo FULLSCREENSWITCH_HOTKEY=$FULLSCREENSWITCH_HOTKEY
|
||||
|
||||
}
|
||||
|
||||
list_descendants() {
|
||||
local children=$(ps -o pid= --ppid "$1")
|
||||
for pid in $children ; do
|
||||
list_descendants "$pid"
|
||||
done
|
||||
echo "$children"
|
||||
}
|
||||
|
||||
#Clean function
|
||||
finish() {
|
||||
#echo ; echo TRAP: finish.
|
||||
|
||||
if ! [ "$REXEC_EXIT" = "" ] ; then
|
||||
print_pending "Executing $REXEC_EXIT"
|
||||
$SSH_EXEC "bash -s" < "$REXEC_EXIT"
|
||||
print_ok "$REXEC_EXIT exited."
|
||||
fi
|
||||
|
||||
#ffplay and/or ffmpeg may hangs on remote, kill them by name
|
||||
# $SSH_EXEC "killall $FFPLAYEXE" &>/dev/null
|
||||
# $SSH_EXEC "killall $FFMPEGEXE" &>/dev/null
|
||||
$SSH_EXEC "kill \$(pidof FFPLAYEXE)" &>/dev/null
|
||||
$SSH_EXEC "kill \$(pidof $FFMPEGEXE)" &>/dev/null
|
||||
sleep 1
|
||||
# $SSH_EXEC "killall -9 $FFPLAYEXE" &>/dev/null
|
||||
# $SSH_EXEC "killall -9 $FFMPEGEXE" &>/dev/null
|
||||
$SSH_EXEC "kill -9 \$(pidof $FFPLAYEXE)" &>/dev/null
|
||||
$SSH_EXEC "kill -9 \$(pidof $FFMPEGEXE)" &>/dev/null
|
||||
$SSH_EXEC "unlink $FFMPEGEXE" &>/dev/null
|
||||
$SSH_EXEC "unlink $FFPLAYEXE" &>/dev/null
|
||||
#kill multiplexing ssh
|
||||
ssh -O exit -o ControlPath="$SSH_CONTROL_PATH" $RHOST 2>/dev/null
|
||||
kill $(list_descendants $$) &>/dev/null
|
||||
|
||||
rm $NESCRIPT &>/dev/null
|
||||
rm $NE_CMD_SOCK&>/dev/null
|
||||
|
||||
}
|
||||
|
||||
#Test and report net download speed
|
||||
benchmark_net() {
|
||||
$SSH_EXEC sh -c '"timeout 1 dd if=/dev/zero bs=1b "' | cat - > /tmp/$$_zero_$$
|
||||
KBPS=$(( $(wc -c < /tmp/$$_zero_$$) *8/1000 ))
|
||||
echo $KBPS
|
||||
rm /tmp/$$_zero_$$
|
||||
}
|
||||
|
||||
FS="F"
|
||||
setup_input_loop() {
|
||||
#Parse remote hotkeys and perform local actions (eg: Fullscreen switching)
|
||||
print_pending "Setting up input loop and forwarding devices"
|
||||
#Prepare netevent script
|
||||
i=1
|
||||
touch $NESCRIPT
|
||||
KBDNAME=$(<$KBDFILE)
|
||||
|
||||
# From 2.2.1, netevent splitted grab in grab-devices and write-events
|
||||
# it also introduced the -V switch; check if it reports anything with -V
|
||||
# to react to the change.
|
||||
netevent_version=$(netevent 2>/dev/null -V)
|
||||
if ! [ "_$netevent_version" == "_" ] ; then netevent_is="NEW" ; fi
|
||||
|
||||
for DEVICE in $(<$ICFILE_RUNTIME) ; do
|
||||
echo " forward input from device $DEVICE..."
|
||||
DEVNAME=$(name_from_event "$DEVICE")
|
||||
if [ "$DEVNAME" = "$KBDNAME" ] ; then # Device is keyboard -> add it and setup hotkeys
|
||||
echo "device add mykbd$i /dev/input/$DEVICE" >>$NESCRIPT
|
||||
if [ $netevent_is == "NEW" ] ; then
|
||||
echo "hotkey add mykbd$i key:$GRAB_HOTKEY:0 'write-events toggle ; grab-devices toggle'" >>$NESCRIPT
|
||||
else
|
||||
echo "hotkey add mykbd$i key:$GRAB_HOTKEY:0 grab toggle" >>$NESCRIPT
|
||||
fi
|
||||
echo "action set grab-changed exec '/usr/bin/echo Is input forwarded 1=Yes,0=No ? \$NETEVENT_GRABBING' " >>$NESCRIPT
|
||||
echo "hotkey add mykbd$i key:$GRAB_HOTKEY:1 nop" >>$NESCRIPT
|
||||
echo "hotkey add mykbd$i key:$FULLSCREENSWITCH_HOTKEY:0 exec \"/usr/bin/echo FULLSCREENSWITCH_HOTKEY\"" >>$NESCRIPT
|
||||
echo "hotkey add mykbd$i key:$FULLSCREENSWITCH_HOTKEY:1 nop" >>$NESCRIPT
|
||||
else # Device is not keyboard -> just add it
|
||||
echo "device add dev$i /dev/input/$DEVICE" >>$NESCRIPT
|
||||
fi
|
||||
let i=i+1
|
||||
done
|
||||
echo "output add myremote exec:$SSH_EXEC netevent create" >>$NESCRIPT
|
||||
echo "use myremote" >>$NESCRIPT
|
||||
|
||||
echo
|
||||
print_pending "Starting netevent daemon with script $NESCRIPT"
|
||||
netevent daemon -s $NESCRIPT $NE_CMD_SOCK | while read -r hotkey; do
|
||||
echo "read hotkey: " $hotkey
|
||||
if [ "$hotkey" = "FULLSCREENSWITCH_HOTKEY" ] ; then
|
||||
if [ "$FS" = "F" ] ; then
|
||||
wmctrl -b add,fullscreen -r "$WTITLE"
|
||||
wmctrl -b add,above -r "$WTITLE"
|
||||
FS="T"
|
||||
else
|
||||
wmctrl -b remove,fullscreen -r "$WTITLE"
|
||||
wmctrl -b remove,above -r "$WTITLE"
|
||||
FS="F"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
deps_or_exit(){
|
||||
#Check that dependancies are ok, or exits the script
|
||||
check_local_input_group
|
||||
check_remote_uinput_access
|
||||
DEPS_L="bash grep head cut timeout sleep tee netevent wc wmctrl awk basename ssh ffplay mpv ["
|
||||
DEPS_OPT_L=""
|
||||
DEPS_R="bash timeout dd ffmpeg pactl grep awk tail xdpyinfo netevent"
|
||||
|
||||
#Local deps
|
||||
for d in $DEPS_L ; do
|
||||
ERROR=0
|
||||
if ! which $d &>/dev/null ; then
|
||||
print_error "Cannot find required local executable: $d"
|
||||
ask_continue_or_exit
|
||||
fi
|
||||
done
|
||||
for d in $DEPS_OPT_L ; do
|
||||
if ! which $d &>/dev/null ; then
|
||||
print_warning "Cannot find required optional executable: $d"
|
||||
fi
|
||||
done
|
||||
|
||||
#Remote deps
|
||||
for d in $DEPS_R ; do
|
||||
ERROR=0
|
||||
if ! $SSH_EXEC "which $d &>/dev/null" ; then
|
||||
print_error "Cannot find required remote executable: $d"
|
||||
ask_continue_or_exit
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# ### MAIN ### ### MAIN ### ### MAIN ### ### MAIN ###
|
||||
|
||||
if [ "$1 " = "inputconfig " ] ; then
|
||||
create_input_files
|
||||
exit
|
||||
fi
|
||||
|
||||
#Parse arguments
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
arg="$1"
|
||||
case $arg in
|
||||
-u|--user)
|
||||
RUSER="$2"
|
||||
shift ; shift ;;
|
||||
-s|--server)
|
||||
RHOST="$2"
|
||||
shift ; shift ;;
|
||||
-p|--port)
|
||||
RPORT="$2"
|
||||
shift ; shift ;;
|
||||
--sshopt)
|
||||
SSHOPT="$2"
|
||||
shift ; shift ;;
|
||||
-d|--display)
|
||||
RDISPLAY="$2"
|
||||
shift ; shift ;;
|
||||
-r|--resolution)
|
||||
RES="$2"
|
||||
shift ; shift ;;
|
||||
--prescale)
|
||||
PRESCALE="$2"
|
||||
shift ; shift ;;
|
||||
-o|--offset)
|
||||
OFFSET="$2"
|
||||
shift ; shift ;;
|
||||
--follow)
|
||||
FOLLOW_STRING='-follow_mouse 1'
|
||||
shift ;;
|
||||
-f|--fps)
|
||||
FPS="$2"
|
||||
shift ; shift ;;
|
||||
--pasource)
|
||||
AUDIO_CAPTURE_SOURCE="$2"
|
||||
shift ; shift ;;
|
||||
--videoenc)
|
||||
VIDEOENC="$2"
|
||||
shift ; shift ;;
|
||||
--audioenc)
|
||||
AUDIOENC="$2"
|
||||
shift ; shift ;;
|
||||
--customv)
|
||||
VIDEO_ENC_CUSTOM="$2"
|
||||
shift ; shift ;;
|
||||
--customa)
|
||||
AUDIO_ENC_CUSTOM="$2"
|
||||
shift ; shift ;;
|
||||
--audioenc)
|
||||
AUDIOENC="$2"
|
||||
shift ; shift ;;
|
||||
#--videoplayer)
|
||||
# VIDEOPLAYER="$2"
|
||||
# shift ; shift ;;
|
||||
--vplayeropts)
|
||||
VPLAYEROPTS="$2"
|
||||
shift ; shift ;;
|
||||
-v|--vbitrate)
|
||||
VIDEO_BITRATE_MAX="$2"
|
||||
shift ; shift ;;
|
||||
-a|--abitrate)
|
||||
AUDIO_BITRATE="$2"
|
||||
shift ; shift ;;
|
||||
--rexec-before)
|
||||
REXEC_BEFORE="$2"
|
||||
shift ; shift ;;
|
||||
--rexec-exit)
|
||||
REXEC_EXIT="$2"
|
||||
shift ; shift ;;
|
||||
*)
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Decoding
|
||||
#ffplay, low latency, no hardware decoding
|
||||
#VIDEOPLAYER="ffplay - -vf "setpts=0.5*PTS" -nostats -window_title "$WTITLE" -probesize 32 -flags low_delay -framedrop -fflags nobuffer+fastseek+flush_packets -analyzeduration 0 -sync ext"
|
||||
|
||||
#mpv, less latency, possibly hardware decoding, may hammer the cpu.
|
||||
#Untimed:
|
||||
#VIDEOPLAYER="taskset -c 0 mpv - --input-cursor=no --input-vo-keyboard=no --input-default-bindings=no --hwdec=auto --title="$WTITLE" --untimed --no-cache --profile=low-latency --opengl-glfinish=yes --opengl-swapinterval=0"
|
||||
|
||||
#speed=2 instead of untimed, seems smoother:
|
||||
VIDEOPLAYER="taskset -c 0 mpv - --input-cursor=no --input-vo-keyboard=no --input-default-bindings=no --hwdec=auto --title="$WTITLE" --speed=2 --no-cache --profile=low-latency --opengl-glfinish=yes --opengl-swapinterval=0 $VPLAYEROPTS"
|
||||
|
||||
#less hammering, experimental, introduce some stuttering :/
|
||||
#VIDEOPLAYER="taskset -c 0 mpv - --input-cursor=no --input-vo-keyboard=no --input-default-bindings=no --hwdec=auto --title="$WTITLE" --speed=2 --no-cache --profile=low-latency --opengl-glfinish=yes --opengl-swapinterval=0 --cache-pause=yes --cache-pause-wait=0.001"
|
||||
|
||||
#older mpv versions, vaapi
|
||||
#VIDEOPLAYER="taskset -c 0 mpv - --input-cursor=no --input-vo-keyboard=no --input-default-bindings=no --hwdec=vaapi --vo=gpu --gpu-api=opengl --title="$WTITLE" --untimed --no-cache --audio-buffer=0 --vd-lavc-threads=1 --cache-pause=no --demuxer-lavf-o=fflags=+nobuffer --demuxer-lavf-analyzeduration=0.1 --video-sync=audio --interpolation=no --opengl-glfinish=yes --opengl-swapinterval=0"
|
||||
|
||||
AUDIOPLAYER="ffplay - -nostats -loglevel warning -flags low_delay -nodisp -probesize 32 -fflags nobuffer+fastseek+flush_packets -analyzeduration 0 -sync ext -af aresample=async=1:min_comp=0.1:first_pts=$AUDIO_DELAY_COMPENSATION"
|
||||
|
||||
if [ "$AUDIOENC" = "show" ] || [ "$VIDEOENC" = "show" ] ; then
|
||||
if [ "$AUDIOENC" = "show" ] ; then
|
||||
print_pending "Audio encoding presets: \
|
||||
\n opus: \"$AUDIO_ENC_OPUS\" \
|
||||
\n pcm: \"$AUDIO_ENC_PCM\" \
|
||||
\n"
|
||||
fi
|
||||
|
||||
if [ "$VIDEOENC" = "show" ] ; then
|
||||
print_pending "Video encoding presets: \
|
||||
\n cpu: \"$VIDEO_ENC_CPU\" \
|
||||
\n cpurgb: \"$VIDEO_ENC_CPU_RGB\" \
|
||||
\n amdgpu: \"$VIDEO_ENC_AMDGPU\" \
|
||||
\n amdgpu_hevc: \"$VIDEO_ENC_AMDGPU_HEVC\" \
|
||||
\n intelgpu: \"$VIDEO_ENC_INTELGPU\" \
|
||||
\n nvgpu: \"$VIDEO_ENC_NVGPU\" \
|
||||
\n nvgpu_hevc: \"$VIDEO_ENC_NVGPU_HEVC\" \
|
||||
\n"
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
|
||||
me=$(basename "$0")
|
||||
if [ -z $RUSER ] || [ -z $RHOST ] || [ "$1" = "-h" ] ; then
|
||||
echo Please edit "$me" to suit your needs and/or use the following options:
|
||||
echo Usage: "$me" "[OPTIONS]"
|
||||
echo ""
|
||||
echo "OPTIONS"
|
||||
echo ""
|
||||
echo "Use $me inputconfig to create or change the input config file"
|
||||
echo ""
|
||||
echo "-s, --server Remote host to connect to"
|
||||
echo "-u, --user ssh username"
|
||||
echo "-p, --port ssh port"
|
||||
echo " --sshopt pass additional ssh option (omit -o)"
|
||||
echo "-d, --display Remote display (eg: 0.0)"
|
||||
echo "-r, --resolution Grab size (eg: 1920x1080) or AUTO"
|
||||
echo "-o, --offset Grab offset (eg: +1920,0)"
|
||||
echo " --follow pan the grabbed area when the cursor reaches the border"
|
||||
echo " --prescale Scale video before encoding (eg: 1280x720)."
|
||||
echo " Has impact on remote cpu use and can increase latency too."
|
||||
echo "-f, --fps Grabbed frames per second"
|
||||
echo " --pasource Capture from the specified pulseaudio source. (experimental and may introduce delay)"
|
||||
echo " Use AUTO to guess, use ALL to capture everything."
|
||||
echo " Eg: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor"
|
||||
echo ""
|
||||
echo " --videoenc Video encoder can be: cpu,cpurgb,amdgpu,amdgpu_hevc,intelgpu,nvgpu,nvgpu_hevc,zerocopy,custom or show"
|
||||
echo " \"zerocopy\" is experimental and causes ffmpeg to use kmsgrab"
|
||||
echo " to grab the framebuffer and pass frames to vaapi encoder."
|
||||
echo " You've to run 'setcap cap_sys_admin+ep $(which ffmpeg)' on the server to use zerocopy."
|
||||
echo " --display, --follow are ignored when using zerocopy."
|
||||
echo " specify \"show\" to print the options for each preset."
|
||||
echo ""
|
||||
echo " --customv Specify a string for video encoder stuff when videoenc is set to custom"
|
||||
echo " Eg: \"-threads 1 -c:v h264_nvenc -preset llhq -delay 0 -zerolatency 1\""
|
||||
echo " --audioenc Audio encoder can be: opus,pcm,null,custom or show"
|
||||
echo " \"null\" disables audio grabbing completely"
|
||||
echo " specify \"show\" to print the options for each other preset."
|
||||
echo ""
|
||||
echo " --customa Specify a string for audio encoder stuff when videoenc is set to custom"
|
||||
echo " Eg: \"-acodec libopus -vbr off -application lowdelay\""
|
||||
echo "-v, --vbitrate Video bitrate in kbps or AUTO"
|
||||
echo " AUTO will use 80% of the maximum available throughput."
|
||||
echo "-a, --abitrate Audio bitrate in kbps"
|
||||
echo " --vplayeropts Additional options to pass to videoplayer"
|
||||
echo " Eg: \"--video-output-levels=limited --video-rotate=90\""
|
||||
echo " --rexec-before Execute the specified script via 'sh' just before the connection"
|
||||
echo " --rexec-exit Execute the specified script via 'sh' before exiting the script"
|
||||
#echo " --videoplayer
|
||||
echo
|
||||
echo "Example 1: john connecting to jserver, all defaults accepted"
|
||||
echo " "$me" --user john --server jserver"
|
||||
echo
|
||||
echo "Example 2:"
|
||||
echo " john connecting to jserver on ssh port 322, streaming the display 0.0"
|
||||
echo " remote setup is dual head and john selects the right monitor."
|
||||
echo " Stream will be 128kbps for audio and 10000kbps for video:"
|
||||
echo " Ex: $me -u john -s jserver -p 322 -d 0.0 -r 1920x1080 -o +1920,0 -f 60 -a 128 -v 10000"
|
||||
echo
|
||||
echo "Example 3:"
|
||||
echo " Bill connecting to jserver on ssh port 322, streaming the display 0.0"
|
||||
echo " Stream will be 128kbps for audio and 10000kbps for video:"
|
||||
echo " Bill wants untouched audio, 144fps and encode via intelgpu, he needs to correct video output levels"
|
||||
echo " Ex: $me -u bill -s bserver -p 322 -d 0.0 -f 144 -v 80000 --audioenc pcm --videoenc intelgpu --vplayeropts \"--video-output-levels=limited\""
|
||||
echo
|
||||
echo "user and host are mandatory."
|
||||
echo "default ssh-port: $RPORT"
|
||||
echo "default DISPLAY : $RDISPLAY"
|
||||
echo "default size : $RES"
|
||||
echo "default offset : $OFFSET"
|
||||
echo "default fps : $FPS"
|
||||
echo "default video encoder: $VIDEOENC"
|
||||
echo "default audio encoder: $AUDIOENC"
|
||||
echo "default abitrate: $AUDIO_BITRATE kbps"
|
||||
echo "default vbitrate: $VIDEO_BITRATE_MAX kbps"
|
||||
exit
|
||||
fi
|
||||
|
||||
#Sanity checks
|
||||
|
||||
RDISPLAY=":$RDISPLAY"
|
||||
|
||||
if [ "$AUDIOENC" = "custom" ] && [ "$AUDIO_ENC_CUSTOM" = "" ] ; then
|
||||
print_error "Custom audioencoder requested, but no custom encoder string provided. use --customa <something>"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$VIDEOENC" = "custom" ] && [ "$VIDEO_ENC_CUSTOM" = "" ] ; then
|
||||
print_notice "Custom video encoder requested, but no custom encoder string provided. use --customv <something>"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -f "$EVDFILE" ] ; then
|
||||
print_error "Input configuration file "$EVDFILE" not found!"
|
||||
echo "Please, Select which devices to share."
|
||||
sleep 2
|
||||
create_input_files
|
||||
fi
|
||||
|
||||
trap finish EXIT
|
||||
trap exit INT TERM
|
||||
|
||||
#Setup SSH Multiplexing
|
||||
SSH_CONTROL_PATH=$HOME/.config/ssh-rdp$$
|
||||
print_pending "Starting ssh multiplexed connection"
|
||||
if ssh -fN -o ControlMaster=auto -o ControlPath=$SSH_CONTROL_PATH -o ControlPersist=60 -o "$SSHOPT" $RUSER@$RHOST -p $RPORT; then
|
||||
print_ok "Started ssh multiplexed connection"
|
||||
else
|
||||
print_warning "Cannot start ssh multiplexed connection"
|
||||
ask_continue_or_exit
|
||||
fi
|
||||
#Shortcut to start remote commands:
|
||||
[ ! "$SSH_CIPHER" = "" ] && SSH_CIPHER=" -c $SSH_CIPHER"
|
||||
SSH_EXEC="ssh $SSH_CIPHER -o ControlMaster=auto -o ControlPath=$SSH_CONTROL_PATH $RUSER@$RHOST -p $RPORT"
|
||||
|
||||
print_pending "Checking required executables..."
|
||||
deps_or_exit
|
||||
print_ok "Checked required executables"
|
||||
echo
|
||||
|
||||
generate_ICFILE_from_names
|
||||
|
||||
#netevent script file and command sock
|
||||
NESCRIPT=/tmp/nescript$$
|
||||
NE_CMD_SOCK=/tmp/neteventcommandsock$$
|
||||
|
||||
#We need to kill some processes on exit, do it by name.
|
||||
FFMPEGEXE=/tmp/ffmpeg$$
|
||||
$SSH_EXEC "ln -s \$(which ffmpeg) $FFMPEGEXE"
|
||||
FFPLAYEXE=/tmp/ffplay$$
|
||||
$SSH_EXEC "ln -s \$(which ffplay) $FFPLAYEXE"
|
||||
|
||||
#Measure network download speed?
|
||||
if [ "$VIDEO_BITRATE_MAX" = "AUTO" ] ; then
|
||||
echo
|
||||
print_pending "Measuring network throughput..."
|
||||
VIDEO_BITRATE_MAX=$(benchmark_net)
|
||||
echo "[OK] VIDEO_BITRATE_MAX = "$VIDEO_BITRATE_MAX"Kbps"
|
||||
VIDEO_BITRATE_MAX=$(( "$VIDEO_BITRATE_MAX" * "$VIDEO_BITRATE_MAX_SCALE" / 100 ))
|
||||
print_ok "Scaled Throughput ("$VIDEO_BITRATE_MAX_SCALE"%) = "$VIDEO_BITRATE_MAX"Kbps"
|
||||
if [ $VIDEO_BITRATE_MAX -gt 294987 ] ; then
|
||||
print_pending "$VIDEO_BITRATE_MAX Kbps" is too high!
|
||||
VIDEO_BITRATE_MAX=100000
|
||||
fi
|
||||
print_warning "Using $VIDEO_BITRATE_MAX Kbps"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
if ! [ "$REXEC_BEFORE" = "" ] ; then
|
||||
print_pending "Executing $REXEC_BEFORE"
|
||||
$SSH_EXEC "bash -s" < "$REXEC_BEFORE"
|
||||
print_ok "$REXEC_BEFORE exited."
|
||||
fi
|
||||
|
||||
setup_input_loop &
|
||||
sleep 0.1 #(just to not shuffle output messages)
|
||||
PID1=$!
|
||||
|
||||
echo
|
||||
print_pending "Trying to connect to $RUSER@$RHOST:$RPORT"
|
||||
echo " and stream display $DISPLAY"
|
||||
echo " with size $RES and offset: $OFFSET"
|
||||
echo
|
||||
|
||||
#Play a test tone to open the pulseaudio sinc prior to recording it to (avoid audio delays at start!?) #This hangs at exit, so we'll kill it by name.
|
||||
$SSH_EXEC "$FFPLAYEXE -loglevel warning -nostats -nodisp -f lavfi -i \"sine=220:4\" -af volume=0.001 -autoexit" &
|
||||
PID5=$!
|
||||
|
||||
|
||||
#Guess audio capture device?
|
||||
if [ "$AUDIO_CAPTURE_SOURCE" = "AUTO" ] ; then
|
||||
print_pending "Guessing audio capture device"
|
||||
AUDIO_CAPTURE_SOURCE=$($SSH_EXEC echo '$(pactl list sources short|grep monitor|awk "{print \$2}" | head -n 1)')
|
||||
# or: AUDIO_CAPTURE_SOURCE=$($SSH_EXEC echo '$(pacmd list-sources | grep "<.*monitor>" |awk -F "[<>]" "{print \$2}" | tail -n 1)')
|
||||
print_warning "Guessed audio capture source: $AUDIO_CAPTURE_SOURCE"
|
||||
echo
|
||||
fi
|
||||
#
|
||||
if [ "$AUDIO_CAPTURE_SOURCE" = "ALL" ] ; then
|
||||
print_pending "Guessing ALL audio capture devices"
|
||||
AUDIO_CAPTURE_SOURCE=$($SSH_EXEC echo '$(pactl list sources short|awk "{print \$2}")')
|
||||
# or: AUDIO_CAPTURE_SOURCE=$($SSH_EXEC echo '$(pacmd list-sources | grep "name\: <.*>" |awk -F "[<>]" "{print \$2}")')
|
||||
print_warning "Guessed following audio capture sources: $AUDIO_CAPTURE_SOURCE"
|
||||
echo
|
||||
fi
|
||||
|
||||
#Auto video grab size?
|
||||
if [ "$RES" = "AUTO" ] || [ "$RES" = "" ] ; then
|
||||
print_pending "Guessing remote resolution"
|
||||
RES=$($SSH_EXEC "export DISPLAY=$RDISPLAY ; xdpyinfo | awk '/dimensions:/ { print \$2; exit }'")
|
||||
# print_warning "Auto grab resolution: $RES"
|
||||
echo
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#Select video encoder:
|
||||
case $VIDEOENC in
|
||||
cpu)
|
||||
VIDEO_ENC="$VIDEO_ENC_CPU" ;;
|
||||
cpurgb)
|
||||
VIDEO_ENC="$VIDEO_ENC_CPU_RGB" ;;
|
||||
nvgpu)
|
||||
VIDEO_ENC="$VIDEO_ENC_NVGPU" ;;
|
||||
nvgpu_hevc)
|
||||
VIDEO_ENC="$VIDEO_ENC_NVGPU_HEVC" ;;
|
||||
amdgpu)
|
||||
VIDEO_ENC="$VIDEO_ENC_AMDGPU" ;;
|
||||
amdgpu_hevc)
|
||||
VIDEO_ENC="$VIDEO_ENC_AMDGPU_HEVC" ;;
|
||||
custom)
|
||||
VIDEO_ENC="$VIDEO_ENC_CUSTOM" ;;
|
||||
intelgpu)
|
||||
VIDEO_ENC="$VIDEO_ENC_INTELGPU" ;;
|
||||
zerocopy)
|
||||
VIDEO_ENC="" ;;
|
||||
*)
|
||||
print_error "Unsupported video encoder"
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#Select audio encoder:
|
||||
case $AUDIOENC in
|
||||
opus)
|
||||
AUDIO_ENC="$AUDIO_ENC_OPUS";;
|
||||
pcm)
|
||||
AUDIO_ENC="$AUDIO_ENC_PCM" ;;
|
||||
custom)
|
||||
AUDIO_ENC="$AUDIO_ENC_CUSTOM" ;;
|
||||
null)
|
||||
AUDIO_ENC="null" ;;
|
||||
*)
|
||||
print_error "Unsupported audio encoder"
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#Insert the scale filter by replacing the dummy filters null,null.
|
||||
if [ ! "$PRESCALE" = "" ] ; then
|
||||
VIDEO_ENC=$(sed "s/null,null/scale=$PRESCALE/" <<< "$VIDEO_ENC")
|
||||
fi
|
||||
|
||||
#Grab Audio
|
||||
if ! [ "$AUDIO_ENC" = "null" ] ; then
|
||||
print_pending "Start audio streaming..."
|
||||
|
||||
for ASOURCE in $AUDIO_CAPTURE_SOURCE ; do
|
||||
AUDIO_SOURCE_GRAB_STRING="$AUDIO_SOURCE_GRAB_STRING -f pulse -ac 2 -fragment_size 1024 -i $ASOURCE "
|
||||
done
|
||||
#insert amix
|
||||
AUDIO_SOURCE_GRAB_STRING="$AUDIO_SOURCE_GRAB_STRING -filter_complex amix=inputs=$(echo $AUDIO_CAPTURE_SOURCE|wc -w)"
|
||||
|
||||
$SSH_EXEC sh -c "\
|
||||
export DISPLAY=$RDISPLAY ;\
|
||||
$FFMPEGEXE -v quiet -nostdin -loglevel warning -y "$AUDIO_SOURCE_GRAB_STRING" -b:a "$AUDIO_BITRATE"k "$AUDIO_ENC" -f nut -\
|
||||
" | $AUDIOPLAYER &
|
||||
PID4=$!
|
||||
fi
|
||||
|
||||
|
||||
#Grab Video
|
||||
print_pending "Start video streaming..."
|
||||
|
||||
#$SSH_EXEC sh -c "\
|
||||
# export DISPLAY=$RDISPLAY ;\
|
||||
# $FFMPEGEXE -nostdin -loglevel warning -y -f x11grab -framerate $FPS -video_size $RES -i "$RDISPLAY""$OFFSET" -sws_flags $SCALE_FLT -b:v #"$VIDEO_BITRATE_MAX"k -maxrate "$VIDEO_BITRATE_MAX"k \
|
||||
# "$VIDEO_ENC" -f_strict experimental -syncpoints none -f nut -\
|
||||
#" | $VIDEOPLAYER
|
||||
|
||||
if [ ! "$VIDEOENC" = "zerocopy" ] ; then
|
||||
$SSH_EXEC sh -c "\
|
||||
export DISPLAY=$RDISPLAY ;\
|
||||
export VAAPI_DISABLE_INTERLACE=1;\
|
||||
$FFMPEGEXE -nostdin -loglevel warning -y -f x11grab "$FOLLOW_STRING" -framerate $FPS -video_size $RES -i "$RDISPLAY""$OFFSET" -sws_flags $SCALE_FLT -b:v "$VIDEO_BITRATE_MAX"k -maxrate "$VIDEO_BITRATE_MAX"k \
|
||||
"$VIDEO_ENC" -f_strict experimental -syncpoints none -f nut -\
|
||||
" | $VIDEOPLAYER
|
||||
else
|
||||
#Zero copy test:
|
||||
RES=$(sed "s/\x/\:/" <<< "$RES")
|
||||
OFFSET=$(sed "s/\+//" <<< "$OFFSET")
|
||||
OFFSET=$(sed "s/\,/:/" <<< "$OFFSET")
|
||||
if [ ! "$PRESCALE" = "" ] ; then
|
||||
NEWRES=$(sed "s/\x/\:/" <<< "$PRESCALE")
|
||||
else
|
||||
NEWRES=$RES
|
||||
fi
|
||||
|
||||
$SSH_EXEC sh -c ";\
|
||||
$FFMPEGEXE -nostdin -loglevel warning -y -framerate $FPS -f kmsgrab -i - -sws_flags $SCALE_FLT -b:v "$VIDEO_BITRATE_MAX"k -maxrate "$VIDEO_BITRATE_MAX"k \
|
||||
-vf hwmap=derive_device=vaapi,crop="$RES:$OFFSET",scale_vaapi="$NEWRES":format=nv12 -c:v h264_vaapi -bf 0 -b:v "$VIDEO_BITRATE_MAX"k -maxrate "$VIDEO_BITRATE_MAX"k -f_strict experimental -syncpoints none -f nut -\
|
||||
" | $VIDEOPLAYER
|
||||
fi
|
||||
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -Eu
|
||||
|
||||
current_pgid=$(ps -o pgid= $$ | tr -d ' ')
|
||||
current_sid=$(ps -o sid= $$ | tr -d ' ')
|
||||
|
||||
function cleanup {
|
||||
echo "│ Cleanup function"
|
||||
# ps xao user,pid,pgid,sid,user,cmd | grep -P '(sshlog|tail)'
|
||||
sudo pkill -9 -g $current_pgid -s $current_sid
|
||||
}
|
||||
|
||||
trap cleanup SIGINT INT TERM QUIT ERR
|
||||
|
||||
TAILOPTS=''
|
||||
TAILLINES=''
|
||||
CAT=0
|
||||
GREP_PATTERN=''
|
||||
GREP_OPT=''
|
||||
NOCOLOR=0
|
||||
LOG_MAP='{
|
||||
"default": {
|
||||
"default": "cmd:journalctl --output cat"
|
||||
},
|
||||
"host": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"vrack": "/var/log/neutron/neutron-ovh-vrack-agent.log",
|
||||
"bgp": "/var/log/neutron/neutron-ovh-bgp-agent.log",
|
||||
"l3": "/var/log/neutron/neutron-ovh-l3-agent.log",
|
||||
"metadata": "/var/log/neutron/neutron-ovh-metadata-agent.log",
|
||||
"nova": "/var/log/nova/*.log",
|
||||
"libvirt": "/var/log/libvirt/libvirtd.log",
|
||||
"ovs": "/var/log/openvswitch/*.log",
|
||||
"neutron": "/var/log/neutron/*.log",
|
||||
"default": "/var/log/nova/*.log /var/log/neutron/*.log"
|
||||
},
|
||||
"snat": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"vrack": "/var/log/neutron/neutron-ovh-vrack-agent.log",
|
||||
"bgp": "/var/log/neutron/neutron-ovh-bgp-agent.log",
|
||||
"l3": "/var/log/neutron/neutron-ovh-l3-agent.log",
|
||||
"dhcp": "/var/log/neutron/neutron-dhcp-agent.log",
|
||||
"metadata": "/var/log/neutron/neutron-ovh-metadata-agent.log",
|
||||
"neutron": "/var/log/neutron/*.log",
|
||||
"ovs": "/var/log/openvswitch/*.log",
|
||||
"default": "/var/log/neutron/*.log"
|
||||
},
|
||||
"neutron": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"apache": "/var/log/apache2/neutron-api*log",
|
||||
"api": "/var/log/neutron/neutron-api.log",
|
||||
"rpc": "/var/log/neutron/neutron-rpc.log",
|
||||
"default": "/var/log/neutron/*.log"
|
||||
},
|
||||
"nova": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"apache": "/var/log/apache2/nova-api*log",
|
||||
"api": "/var/log/nova/nova-api.log",
|
||||
"conductor": "/var/log/nova/nova-conductor.log",
|
||||
"scheduler": "/var/log/nova/nova-scheduler.log",
|
||||
"placement": "/var/log/placement/placement-api.log",
|
||||
"default": "/var/log/nova/*.log"
|
||||
},
|
||||
"cinder": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"apache": "/var/log/apache2/cinder-api*log",
|
||||
"api": "/var/log/cinder/cinder-api.log",
|
||||
"scheduler": "/var/log/cinder/cinder-scheduler.log",
|
||||
"volume": "/var/log/cinder/cinder-volume.log",
|
||||
"backup": "/var/log/cinder/cinder-backup.log",
|
||||
"default": "/var/log/cinder/*.log"
|
||||
},
|
||||
"glance": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"default": "/var/log/glance/*.log"
|
||||
},
|
||||
"ironic": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"api": "/var/log/ironic/ironic-api.log",
|
||||
"conductor": "/var/log/ironic/ironic-ovh-conductor.log",
|
||||
"metadata": "/var/log/ironic/ironic-ovh-metadata-server.log",
|
||||
"neutron": "/var/log/neutron/*.log",
|
||||
"nova": "/var/log/nova/*log",
|
||||
"default": "/var/log/ironic/*.log"
|
||||
},
|
||||
"rabbit": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"default": "/var/log/rabbitmq/*.log"
|
||||
},
|
||||
"rabbit-nova": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"default": "/var/log/rabbitmq/*.log"
|
||||
},
|
||||
"rabbit-neutron": {
|
||||
"journal": "cmd:journalctl --output cat",
|
||||
"default": "/var/log/rabbitmq/*.log"
|
||||
}
|
||||
}'
|
||||
|
||||
function sshlog {
|
||||
HOST_GROUP="$1"
|
||||
LOG_KEYS=(${2:-default})
|
||||
|
||||
# Get matching host from /etc/hosts - retrieve maximum MAX_HOSTS
|
||||
found_hosts=$(cat /etc/hosts | \
|
||||
grep -Pv '(^#|^$)' | \
|
||||
awk '{print $2}' | \
|
||||
grep -Pi "^($HOST_GROUP|$HOST_GROUP[0-9]*\.${OS_REGION_NAME:-.*}\..*)$" | head -n ${MAX_HOSTS:-10} | xargs
|
||||
)
|
||||
|
||||
# Get group from host arg
|
||||
len=$(echo $found_hosts | wc -w)
|
||||
if [[ $len -eq 0 ]]; then
|
||||
echo no host found
|
||||
exit 1
|
||||
elif [[ $len -eq 1 ]]; then
|
||||
group_name=$(echo $found_hosts | cut -d. -f1 | tr -d '[0-9]')
|
||||
else
|
||||
group_name=$HOST_GROUP
|
||||
fi
|
||||
|
||||
# Find matching group from LOG_MAP
|
||||
found_group=$(echo $LOG_MAP | jq -r 'keys[]' | grep -P "^$group_name$" || true)
|
||||
if [[ -z $found_group ]]; then
|
||||
# fallback on default group
|
||||
group_name="default"
|
||||
fi
|
||||
|
||||
# get log files from map[group][key]
|
||||
log_files=()
|
||||
for key in ${LOG_KEYS[@]}; do
|
||||
found_log=$(echo $LOG_MAP | jq .\"$group_name\" | jq -r 'keys[]' | grep -P "^$key$" || true)
|
||||
if [[ -z $found_log ]]; then
|
||||
echo "[$key] does not match any of $(echo $LOG_MAP | jq .\"$group_name\" | jq 'keys[]')"
|
||||
exit 1
|
||||
fi
|
||||
log_files+=($(echo $LOG_MAP | jq -r .\"$group_name\".\"$found_log\"))
|
||||
done
|
||||
|
||||
# build logging command
|
||||
if [[ ${log_files[@]} =~ cmd: ]]; then
|
||||
if [[ ${#LOG_KEYS[@]} > 1 ]]; then
|
||||
echo "${log_files[@]} have cmd:xx -- only 1 log arg supported"
|
||||
exit 1
|
||||
fi
|
||||
CMD=$(echo ${log_files[@]} | sed -e 's/^cmd://')
|
||||
LOGCMD="echo '==> $CMD <==' ; timeout 3600 $CMD $TAILOPTS"
|
||||
else
|
||||
LOGCMD="timeout 3600 tail -v $TAILOPTS ${log_files[@]}"
|
||||
fi
|
||||
|
||||
if [[ -n $GREP_PATTERN ]]; then
|
||||
[[ -z $GREP_OPT ]] && GREP_OPT='-Pi'
|
||||
GREPCMD="grep --line-buffered ${GREP_OPT} '$GREP_PATTERN'"
|
||||
else
|
||||
GREPCMD=tee
|
||||
fi
|
||||
|
||||
echo "│"
|
||||
echo "│ Host: $found_hosts"
|
||||
echo "│ Files: ${log_files[@]}"
|
||||
echo "│ Cmd: $LOGCMD | $GREPCMD"
|
||||
echo "│"
|
||||
|
||||
if [[ $NOCOLOR -eq 1 ]]; then
|
||||
color_cmd="tee"
|
||||
else
|
||||
color_cmd="os-log-color"
|
||||
fi
|
||||
|
||||
for h in $(echo $found_hosts); do
|
||||
short=$(echo $h | sed -e 's/\.cloud.ovh.*//')
|
||||
# Execute tail cmd through ssh
|
||||
# stdbuf -o0 : do not buffer stdout
|
||||
# awk: prefix each line whith "host filename ..." # filename is retrieved using tail -v
|
||||
# grep -F '' --line-buffered: try to not mix output
|
||||
sudo ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -l admin $h \
|
||||
"$LOGCMD | $GREPCMD" 2> /dev/null | \
|
||||
stdbuf -o0 awk -v host=$short '/^==>/{size=split($2,splitted,"/");filename=splitted[size] ;next} !/^==>/{print host,filename,$0}' | \
|
||||
grep -F '' --line-buffered &
|
||||
done | $color_cmd
|
||||
|
||||
wait
|
||||
cleanup
|
||||
}
|
||||
|
||||
function sshlog_completion
|
||||
{
|
||||
local cur first
|
||||
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
first=${COMP_WORDS[1]}
|
||||
|
||||
case ${COMP_CWORD} in
|
||||
1) COMPREPLY=($(compgen -W "$(sshlog -s | jq -r 'keys[]'| xargs) $(cat /etc/hosts | grep -Pv '(^#|^$)' | awk '{print $2}' | grep -Pi "[0-9]\.${OS_REGION_NAME:-.*}\." | xargs)" -- ${first})) ;;
|
||||
*) group=$(echo $first | cut -d. -f1 | tr -d "[0-9]");
|
||||
sshlog_group=$(sshlog -s | jq -r .\"${group}\")
|
||||
[[ ! $sshlog_group = null ]] && sshlog_group=$group || sshlog_group=default
|
||||
COMPREPLY=($(compgen -W "$(sshlog -s | jq -r .\"${sshlog_group}\" | jq 'keys[]'| xargs 2> /dev/null)" -- ${cur})) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
function print_help {
|
||||
echo "
|
||||
$(basename $0) [group|hostname] [log type]
|
||||
|
||||
Options:
|
||||
|
||||
$(declare -f main | \
|
||||
grep -P '(help=|--|-[a-zA-Z]\))' | \
|
||||
xargs | \
|
||||
sed -e 's/; /\n/g' -e 's/help=/#/g' | \
|
||||
column -t -s '#')
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
function main {
|
||||
[[ $# == 0 ]] && print_help
|
||||
|
||||
while [[ $# -ne 0 ]]; do
|
||||
arg="$1"; shift
|
||||
case "$arg" in
|
||||
-n)
|
||||
help="NB: nb lines. tail option"
|
||||
export TAILLINES=$1 && shift;;
|
||||
--nocolor|-N)
|
||||
help="no color"
|
||||
export NOCOLOR=1 ;;
|
||||
--cat|-c)
|
||||
help="cat instead tail -f"
|
||||
export CAT=1 ;;
|
||||
--grep|-g)
|
||||
help="grep -Pi pattern"
|
||||
export GREP_PATTERN=$1 && shift;;
|
||||
--grepopt|-G)
|
||||
help="grep options, default -Pi"
|
||||
export GREP_OPT=$1
|
||||
[[ ! $GREP_OPT =~ ^\- ]] && echo "grep opt should begin with ^-.." && exit 1
|
||||
shift;;
|
||||
--show|-s)
|
||||
help="display log map"
|
||||
echo $LOG_MAP ; exit ;;
|
||||
--max|-m)
|
||||
help="maximum nb hosts o get log from"
|
||||
export MAX_HOSTS=$1 && shift ;;
|
||||
--completion)
|
||||
help='completion function (eval "$(sshlog --completion)")'
|
||||
declare -f sshlog_completion
|
||||
echo complete -F sshlog_completion sshlog
|
||||
exit ;;
|
||||
--help|-h)
|
||||
help="this help"
|
||||
print_help ;;
|
||||
*) [[ ! $arg =~ ^\-+.* ]] && POSITIONNAL_ARGS+=($arg) || EXTRA_ARGS+=($arg)
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $CAT -eq 1 ]]; then
|
||||
export TAILLINES="+1"
|
||||
else
|
||||
export TAILOPTS="$TAILOPTS -f"
|
||||
fi
|
||||
|
||||
if [[ -n $TAILLINES ]]; then
|
||||
export TAILOPTS="$TAILOPTS -n $TAILLINES"
|
||||
fi
|
||||
|
||||
HOST_GROUP=${POSITIONNAL_ARGS[0]}
|
||||
LOG_KEYS=${POSITIONNAL_ARGS[@]:1}
|
||||
|
||||
sshlog "$HOST_GROUP" "${LOG_KEYS[@]}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
#!/bin/bash
|
||||
wifi_iface=$( nmcli -f DEVICE,TYPE dev | grep wifi | awk '{print $1}' )
|
||||
|
||||
function wifi_state ()
|
||||
{
|
||||
state="$1"
|
||||
|
||||
if [[ $state == 'on' || $state == 'off' ]]; then
|
||||
nmcli radio wifi $state
|
||||
else
|
||||
error "Unknow state: $state"
|
||||
fi
|
||||
}
|
||||
|
||||
function wifi_list ()
|
||||
{
|
||||
echo "* Available ssid"
|
||||
echo -e "-----------------------------------------------------------------------------\n"
|
||||
nmcli dev wifi list
|
||||
|
||||
echo -e "\n* Created connection"
|
||||
echo -e "-----------------------------------------------------------------------------\n"
|
||||
nmcli con
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
function _ssid_exist ()
|
||||
{
|
||||
ssid="$1"
|
||||
nmcli -t --field ssid dev wifi list | grep -Pq "^$ssid$"
|
||||
return $?
|
||||
}
|
||||
|
||||
function _con_exist ()
|
||||
{
|
||||
name="$1"
|
||||
nmcli -t --field name con | grep -Pq "^$name$"
|
||||
return $?
|
||||
}
|
||||
|
||||
|
||||
function _wifi_security ()
|
||||
{
|
||||
ssid="$1"
|
||||
|
||||
while read wifi; do
|
||||
name=$(echo $wifi | cut -d: -f1)
|
||||
security=$(echo $wifi | cut -d: -f2)
|
||||
if [[ "$name" == "$ssid" ]];then
|
||||
[[ $security =~ WPA ]] && echo 'wpa' && return
|
||||
[[ $security =~ WEP ]] && echo 'wep' && return
|
||||
[[ $security == '' ]] && echo 'none' && return
|
||||
fi
|
||||
done < <( nmcli -t --field ssid,security dev wifi list )
|
||||
|
||||
# not found
|
||||
error "security $security not known type"
|
||||
}
|
||||
|
||||
function wifi_add ()
|
||||
{
|
||||
ssid="$1"
|
||||
name="$2"
|
||||
[[ -z $name ]] && name=$ssid
|
||||
|
||||
_ssid_exist "$ssid"
|
||||
[[ $? -ne 0 ]] && error "Unable to find ssid $ssid"
|
||||
|
||||
security=$(_wifi_security "$ssid")
|
||||
|
||||
echo "- Create new connection $name to ssid: $ssid"
|
||||
ret=$( nmcli con add con-name "$name" ifname $wifi_iface type wifi ssid "$ssid" )
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Fail to add connection: $name | ssid: $ssid : $ret"
|
||||
nmcli con delete "$name" 2> /dev/null
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ $security != 'none' ]]; then
|
||||
read -p "Password: " pass
|
||||
nmcli con modify "$name" wifi-sec.key-mgmt wpa-psk
|
||||
nmcli con modify "$name" wifi-sec.psk "$pass"
|
||||
fi
|
||||
|
||||
echo "- Connection added"
|
||||
}
|
||||
|
||||
function wifi_connect ()
|
||||
{
|
||||
name="$1"
|
||||
_con_exist "$name"
|
||||
[[ $? -ne 0 ]] && error "Unable to find connection $name"
|
||||
|
||||
nmcli con up $name
|
||||
}
|
||||
|
||||
function error
|
||||
{
|
||||
error="$@"
|
||||
echo "[ERROR] $error"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function print_help ()
|
||||
{
|
||||
echo "
|
||||
nmcli wrapper
|
||||
|
||||
$(basename $0) [--list|--add|--name|--connect|--state]
|
||||
|
||||
--list list available ssid
|
||||
--add SSID add wifi connexion
|
||||
--name NAME use with --add to save connection as alias NAME
|
||||
--connect connect to SSID/NAME
|
||||
--state on|off turn wifi on/off
|
||||
|
||||
Ex:
|
||||
$(basename $0) --add bbox-1234 --name Home
|
||||
$(basename $0) --name Home --connect
|
||||
$(basename $0) --add bbox-1234 --name Home --connect
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
function main ()
|
||||
{
|
||||
[[ $# -eq 0 ]] && print_help
|
||||
|
||||
while [[ $# -ne 0 ]]; do
|
||||
arg="$1"; shift
|
||||
case "$arg" in
|
||||
--list) wifi_list ;;
|
||||
--state) state="$1"; shift ;;
|
||||
--add) ssid="$1"; shift ;;
|
||||
--name) name="$1"; shift ;;
|
||||
--connect) connect=1 ;;
|
||||
--help) print_help ;;
|
||||
* ) [[ $arg =~ ^\-+.* ]] && print_help "$arg unknown" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n $state ]] && wifi_state $state
|
||||
[[ -n $ssid ]] && wifi_add "$ssid" "$name"
|
||||
[[ -z $name ]] && name="$ssid"
|
||||
[[ $connect -eq 1 && -n $name ]] && wifi_connect "$name"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
[colors]
|
||||
draw_bold_text_with_bright_colors = true
|
||||
|
||||
[colors.bright]
|
||||
black = "0x928374"
|
||||
blue = "0x7daea3"
|
||||
cyan = "0x89b482"
|
||||
green = "0xa9b665"
|
||||
magenta = "0xd3869b"
|
||||
red = "0xea6962"
|
||||
white = "0xdfbf8e"
|
||||
yellow = "0xe3a84e"
|
||||
|
||||
[colors.normal]
|
||||
black = "0x251f19"
|
||||
blue = "0x7daea3"
|
||||
cyan = "0x89b482"
|
||||
green = "0xa9b665"
|
||||
magenta = "0xd3869b"
|
||||
red = "0xea6962"
|
||||
white = "0xdfbf8e"
|
||||
yellow = "0xe78a4e"
|
||||
|
||||
[colors.primary]
|
||||
background = "0x181818"
|
||||
foreground = "0xdfbf8e"
|
||||
|
||||
[env]
|
||||
TERM = "xterm-256color"
|
||||
WINIT_X11_SCALE_FACTOR = "1"
|
||||
|
||||
[font]
|
||||
size = 12
|
||||
|
||||
[font.bold]
|
||||
style = "Bold"
|
||||
|
||||
[font.bold_italic]
|
||||
style = "Bold Italic"
|
||||
|
||||
[font.italic]
|
||||
style = "Italic"
|
||||
|
||||
[font.normal]
|
||||
family = "CaskaydiaCove Nerd Font"
|
||||
style = "Regular"
|
||||
|
||||
[font.offset]
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "Paste"
|
||||
key = "V"
|
||||
mods = "Control|Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "Copy"
|
||||
key = "C"
|
||||
mods = "Control|Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "PasteSelection"
|
||||
key = "Insert"
|
||||
mods = "Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ResetFontSize"
|
||||
key = "Key0"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "IncreaseFontSize"
|
||||
key = "Equals"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "IncreaseFontSize"
|
||||
key = "Plus"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "DecreaseFontSize"
|
||||
key = "Minus"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ToggleFullscreen"
|
||||
key = "F11"
|
||||
mods = "None"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "Paste"
|
||||
key = "Paste"
|
||||
mods = "None"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "Copy"
|
||||
key = "Copy"
|
||||
mods = "None"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ClearLogNotice"
|
||||
key = "L"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
chars = "\f"
|
||||
key = "L"
|
||||
mods = "Control"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ScrollPageUp"
|
||||
key = "PageUp"
|
||||
mode = "~Alt"
|
||||
mods = "Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ScrollPageDown"
|
||||
key = "PageDown"
|
||||
mode = "~Alt"
|
||||
mods = "Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ScrollToTop"
|
||||
key = "Home"
|
||||
mode = "~Alt"
|
||||
mods = "Shift"
|
||||
|
||||
[[keyboard.bindings]]
|
||||
action = "ScrollToBottom"
|
||||
key = "End"
|
||||
mode = "~Alt"
|
||||
mods = "Shift"
|
||||
|
||||
[scrolling]
|
||||
history = 5000
|
||||
|
||||
[window]
|
||||
dynamic_padding = false
|
||||
title = "Alacritty"
|
||||
dynamic_title = true
|
||||
|
||||
[window.class]
|
||||
general = "Alacritty"
|
||||
instance = "Alacritty"
|
||||
|
||||
[window.padding]
|
||||
x = 2
|
||||
y = 2
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
# Configuration for Alacritty, the GPU enhanced terminal emulator.
|
||||
|
||||
# Any items in the `env` entry below will be added as
|
||||
# environment variables. Some entries may override variables
|
||||
# set by alacritty itself.
|
||||
env:
|
||||
# TERM variable
|
||||
#
|
||||
# This value is used to set the `$TERM` environment variable for
|
||||
# each instance of Alacritty. If it is not present, alacritty will
|
||||
# check the local terminfo database and use `alacritty` if it is
|
||||
# available, otherwise `xterm-256color` is used.
|
||||
TERM: xterm-256color
|
||||
WINIT_X11_SCALE_FACTOR: "1"
|
||||
|
||||
window:
|
||||
# Window dimensions (changes require restart)
|
||||
#
|
||||
# Specified in number of columns/lines, not pixels.
|
||||
# If both are `0`, this setting is ignored.
|
||||
#dimensions:
|
||||
# columns: 0
|
||||
# lines: 0
|
||||
|
||||
# Window position (changes require restart)
|
||||
#
|
||||
# Specified in number of pixels.
|
||||
# If the position is not set, the window manager will handle the placement.
|
||||
#position:
|
||||
# x: 0
|
||||
# y: 0
|
||||
|
||||
# Window padding (changes require restart)
|
||||
#
|
||||
# Blank space added around the window in pixels. This padding is scaled
|
||||
# by DPI and the specified value is always added at both opposing sides.
|
||||
padding:
|
||||
x: 2
|
||||
y: 2
|
||||
|
||||
# Spread additional padding evenly around the terminal content.
|
||||
dynamic_padding: false
|
||||
|
||||
# Window decorations
|
||||
#
|
||||
# Values for `decorations`:
|
||||
# - full: Borders and title bar
|
||||
# - none: Neither borders nor title bar
|
||||
#
|
||||
# Values for `decorations` (macOS only):
|
||||
# - transparent: Title bar, transparent background and title bar buttons
|
||||
# - buttonless: Title bar, transparent background, but no title bar buttons
|
||||
#decorations: full
|
||||
|
||||
# Startup Mode (changes require restart)
|
||||
#
|
||||
# Values for `startup_mode`:
|
||||
# - Windowed
|
||||
# - Maximized
|
||||
# - Fullscreen
|
||||
#
|
||||
# Values for `startup_mode` (macOS only):
|
||||
# - SimpleFullscreen
|
||||
#startup_mode: Windowed
|
||||
|
||||
# Window title
|
||||
title: Alacritty
|
||||
|
||||
# Window class (Linux/BSD only):
|
||||
class:
|
||||
# Application instance name
|
||||
instance: Alacritty
|
||||
# General application class
|
||||
general: Alacritty
|
||||
|
||||
# GTK theme variant (Linux/BSD only)
|
||||
#
|
||||
# Override the variant of the GTK theme. Commonly supported values are `dark` and `light`.
|
||||
# Set this to `None` to use the default theme variant.
|
||||
#gtk_theme_variant: None
|
||||
|
||||
scrolling:
|
||||
# Maximum number of lines in the scrollback buffer.
|
||||
# Specifying '0' will disable scrolling.
|
||||
history: 5000
|
||||
|
||||
# Number of lines the viewport will move for every line scrolled when
|
||||
# scrollback is enabled (history > 0).
|
||||
#multiplier: 3
|
||||
|
||||
# Scroll to the bottom when new text is written to the terminal.
|
||||
#auto_scroll: false
|
||||
|
||||
# Spaces per Tab (changes require restart)
|
||||
#
|
||||
# This setting defines the width of a tab in cells.
|
||||
#
|
||||
# Some applications, like Emacs, rely on knowing about the width of a tab.
|
||||
# To prevent unexpected behavior in these applications, it's also required to
|
||||
# change the `it` value in terminfo when altering this setting.
|
||||
#tabspaces: 8
|
||||
|
||||
# Font configuration (fc-list)
|
||||
font:
|
||||
normal:
|
||||
# Font family
|
||||
# family: JetBrains Mono
|
||||
family: CaskaydiaCove Nerd Font
|
||||
# family: Hack
|
||||
# family: FiraMono Nerd Font
|
||||
# family: DejaVu Sans Mono
|
||||
style: Regular
|
||||
|
||||
bold:
|
||||
style: Bold
|
||||
|
||||
italic:
|
||||
style: Italic
|
||||
|
||||
bold_italic:
|
||||
style: Bold Italic
|
||||
|
||||
# Point size
|
||||
size: 12
|
||||
|
||||
# Offset is the extra space around each character. `offset.y` can be thought of
|
||||
# as modifying the line spacing, and `offset.x` as modifying the letter spacing.
|
||||
offset:
|
||||
x: 0
|
||||
y: 0
|
||||
|
||||
# Glyph offset determines the locations of the glyphs within their cells with
|
||||
# the default being at the bottom. Increasing `x` moves the glyph to the right,
|
||||
# increasing `y` moves the glyph upwards.
|
||||
#glyph_offset:
|
||||
# x: 0
|
||||
# y: 0
|
||||
|
||||
# If `true`, bold text is drawn using the bright color variants.
|
||||
draw_bold_text_with_bright_colors: true
|
||||
|
||||
colors:
|
||||
primary:
|
||||
background: '0x181818'
|
||||
foreground: '0xdfbf8e'
|
||||
|
||||
normal:
|
||||
black: '0x251f19'
|
||||
red: '0xea6962'
|
||||
green: '0xa9b665'
|
||||
yellow: '0xe78a4e'
|
||||
blue: '0x7daea3'
|
||||
magenta: '0xd3869b'
|
||||
cyan: '0x89b482'
|
||||
white: '0xdfbf8e'
|
||||
|
||||
bright:
|
||||
black: '0x928374'
|
||||
red: '0xea6962'
|
||||
green: '0xa9b665'
|
||||
yellow: '0xe3a84e'
|
||||
blue: '0x7daea3'
|
||||
magenta: '0xd3869b'
|
||||
cyan: '0x89b482'
|
||||
white: '0xdfbf8e'
|
||||
|
||||
|
||||
# Bindings are always filled by default, but will be replaced when a new
|
||||
# binding with the same triggers is defined. To unset a default binding, it can
|
||||
# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for
|
||||
# a no-op if you do not wish to receive input characters for that binding.
|
||||
key_bindings:
|
||||
- { key: V, mods: Control|Shift, action: Paste }
|
||||
- { key: C, mods: Control|Shift, action: Copy }
|
||||
- { key: Insert, mods: Shift, action: PasteSelection }
|
||||
- { key: Key0, mods: Control, action: ResetFontSize }
|
||||
- { key: Equals, mods: Control, action: IncreaseFontSize }
|
||||
- { key: Plus, mods: Control, action: IncreaseFontSize }
|
||||
- { key: Minus, mods: Control, action: DecreaseFontSize }
|
||||
- { key: F11, mods: None, action: ToggleFullscreen }
|
||||
- { key: Paste, mods: None, action: Paste }
|
||||
- { key: Copy, mods: None, action: Copy }
|
||||
- { key: L, mods: Control, action: ClearLogNotice }
|
||||
- { key: L, mods: Control, chars: "\x0c" }
|
||||
- { key: PageUp, mods: Shift, action: ScrollPageUp, mode: ~Alt }
|
||||
- { key: PageDown, mods: Shift, action: ScrollPageDown, mode: ~Alt }
|
||||
- { key: Home, mods: Shift, action: ScrollToTop, mode: ~Alt }
|
||||
- { key: End, mods: Shift, action: ScrollToBottom, mode: ~Alt }
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
[global]
|
||||
monitor = 0
|
||||
follow = mouse
|
||||
geometry = "320x5-15+35"
|
||||
indicate_hidden = yes
|
||||
shrink = no
|
||||
transparency = 0
|
||||
notification_height = 0
|
||||
separator_height = 2
|
||||
padding = 10
|
||||
horizontal_padding = 10
|
||||
frame_width = 1
|
||||
frame_color = "#232323"
|
||||
separator_color = frame
|
||||
sort = yes
|
||||
idle_threshold = 120
|
||||
font = Source Sans Pro 10
|
||||
line_height = 0
|
||||
markup = full
|
||||
format = "<span foreground='#f3f4f5'><b>%s %p</b></span>\n%b"
|
||||
alignment = left
|
||||
show_age_threshold = 60
|
||||
word_wrap = yes
|
||||
ellipsize = middle
|
||||
ignore_newline = no
|
||||
stack_duplicates = true
|
||||
hide_duplicate_count = false
|
||||
show_indicators = yes
|
||||
icon_position = left
|
||||
max_icon_size = 32
|
||||
icon_path = ~/.icons/Paper/16x16/status/:~/.icons/Paper/16x16/devices/:~/.icons/Paper/16x16/apps/
|
||||
sticky_history = yes
|
||||
history_length = 20
|
||||
always_run_script = true
|
||||
startup_notification = false
|
||||
verbosity = mesg
|
||||
corner_radius = 2
|
||||
force_xinerama = false
|
||||
mouse_left_click = close_current
|
||||
mouse_middle_click = do_action
|
||||
mouse_right_click = close_all
|
||||
|
||||
[shortcuts]
|
||||
close = ctrl+space
|
||||
close_all = ctrl+shift+space
|
||||
history = ctrl+grave
|
||||
context = ctrl+shift+period
|
||||
|
||||
[urgency_low]
|
||||
background = "#232323"
|
||||
foreground = "#a8a8a8"
|
||||
timeout = 10
|
||||
|
||||
[urgency_normal]
|
||||
background = "#232323"
|
||||
foreground = "#a8a8a8"
|
||||
timeout = 10
|
||||
|
||||
[urgency_critical]
|
||||
background = "#d64e4e"
|
||||
foreground = "#f0e0e0"
|
||||
frame_color = "#d64e4e"
|
||||
timeout = 0
|
||||
icon = ~/.icons/Paper/16x16/status/dialog-warning.png
|
||||
|
|
@ -0,0 +1 @@
|
|||
config
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
# vim: ft=i3config
|
||||
#
|
||||
# This file has been auto-generated by i3-config-wizard(1).
|
||||
# It will not be overwritten, so edit it as you like.
|
||||
#
|
||||
# Should you change your keyboard layout some time, delete
|
||||
# this file and re-run i3-config-wizard(1).
|
||||
#
|
||||
|
||||
# i3 config file (v4)
|
||||
#
|
||||
# Please see http://i3wm.org/docs/userguide.html for a complete reference!
|
||||
|
||||
set $mod Mod1
|
||||
set $win Mod4
|
||||
|
||||
# Before i3 v4.8, we used to recommend this one as the default:
|
||||
# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||
# The font above is very space-efficient, that is, it looks good, sharp and
|
||||
# clear in small sizes. However, its unicode glyph coverage is limited, the old
|
||||
# X core fonts rendering does not support right-to-left and this being a bitmap
|
||||
# font, it doesn’t scale on retina/hidpi displays.
|
||||
|
||||
force_xinerama no
|
||||
|
||||
# Use Mouse+$mod to drag floating windows to their wanted position
|
||||
floating_modifier $mod
|
||||
new_window pixel 2
|
||||
new_float pixel 2
|
||||
hide_edge_borders smart
|
||||
focus_follows_mouse yes
|
||||
|
||||
# i3 gaps
|
||||
# smart_borders on
|
||||
# gaps inner 5
|
||||
# gaps outer 5
|
||||
|
||||
# kill focused window
|
||||
bindsym $mod+Shift+q kill
|
||||
bindsym $mod+F4 kill
|
||||
bindsym --whole-window $win+button1 kill
|
||||
|
||||
# change focus
|
||||
bindsym $win+Left focus left
|
||||
bindsym $win+Down focus down
|
||||
bindsym $win+Up focus up
|
||||
bindsym $win+Right focus right
|
||||
|
||||
# move focused window
|
||||
bindsym $mod+Shift+Left move left
|
||||
bindsym $mod+Shift+Down move down
|
||||
bindsym $mod+Shift+Up move up
|
||||
bindsym $mod+Shift+Right move right
|
||||
|
||||
# split in horizontal orientation
|
||||
bindsym $mod+h split h
|
||||
|
||||
# split in vertical orientation
|
||||
bindsym $mod+v split v
|
||||
|
||||
# enter fullscreen mode for the focused container
|
||||
bindsym $mod+f fullscreen toggle
|
||||
|
||||
# change container layout (stacked, tabbed, toggle split)
|
||||
bindsym $mod+s layout stacking
|
||||
bindsym $mod+t layout tabbed
|
||||
bindsym $mod+e layout toggle split
|
||||
bindsym $mod+o layout toggle
|
||||
|
||||
# toggle tiling / floating
|
||||
bindsym $mod+space floating toggle
|
||||
|
||||
# change focus between tiling / floating windows
|
||||
bindsym $mod+Shift+space focus mode_toggle
|
||||
|
||||
# focus the parent container
|
||||
bindsym $mod+a focus parent
|
||||
|
||||
# focus the child container
|
||||
bindsym $mod+z focus child
|
||||
|
||||
# border changing
|
||||
bindsym $mod+b border toggle
|
||||
|
||||
# switch to workspace
|
||||
bindsym $mod+Tab workspace back_and_forth
|
||||
workspace_auto_back_and_forth yes
|
||||
bindsym $mod+Right workspace next_on_output
|
||||
bindsym $mod+Left workspace prev_on_output
|
||||
bindsym $mod+1 workspace 1
|
||||
bindsym $mod+2 workspace 2
|
||||
bindsym $mod+3 workspace 3
|
||||
bindsym $mod+4 workspace 4
|
||||
bindsym $mod+5 workspace 5
|
||||
bindsym $mod+6 workspace 6
|
||||
bindsym $mod+7 workspace 7
|
||||
bindsym $mod+8 workspace 8
|
||||
bindsym $mod+9 workspace 9
|
||||
bindsym $mod+0 workspace 10
|
||||
bindsym $mod+minus workspace 11
|
||||
bindsym $mod+equal workspace 12
|
||||
|
||||
# move focused container to workspace
|
||||
bindsym $mod+Shift+1 move container to workspace 1
|
||||
bindsym $mod+Shift+2 move container to workspace 2
|
||||
bindsym $mod+Shift+3 move container to workspace 3
|
||||
bindsym $mod+Shift+4 move container to workspace 4
|
||||
bindsym $mod+Shift+5 move container to workspace 5
|
||||
bindsym $mod+Shift+6 move container to workspace 6
|
||||
bindsym $mod+Shift+7 move container to workspace 7
|
||||
bindsym $mod+Shift+8 move container to workspace 8
|
||||
bindsym $mod+Shift+9 move container to workspace 9
|
||||
bindsym $mod+Shift+0 move container to workspace 10
|
||||
bindsym $mod+Shift+minus move container to workspace 11
|
||||
bindsym $mod+Shift+equal move container to workspace 12
|
||||
|
||||
# focus output
|
||||
bindsym $mod+Ctrl+Left focus output left
|
||||
bindsym $mod+Ctrl+Right focus output right
|
||||
bindsym $mod+Ctrl+Up focus output up
|
||||
bindsym $mod+Ctrl+Down focus output down
|
||||
|
||||
# reload the configuration file
|
||||
bindsym $mod+Shift+c exec "~/.config/i3/i3_build_conf.sh reload"
|
||||
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
|
||||
bindsym $mod+Shift+r exec "~/.config/i3/i3_build_conf.sh restart"
|
||||
# exit i3 (logs you out of your X session)
|
||||
bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
|
||||
|
||||
# resize window (you can also use the mouse for that)
|
||||
mode "resize" {
|
||||
# These bindings trigger as soon as you enter the resize mode
|
||||
|
||||
# Pressing left will shrink the window’s width.
|
||||
# Pressing right will grow the window’s width.
|
||||
# Pressing up will shrink the window’s height.
|
||||
# Pressing down will grow the window’s height.
|
||||
bindsym Left resize shrink width 10 px or 10 ppt
|
||||
bindsym Down resize grow height 10 px or 10 ppt
|
||||
bindsym Up resize shrink height 10 px or 10 ppt
|
||||
bindsym Right resize grow width 10 px or 10 ppt
|
||||
|
||||
# back to normal: Enter or Escape
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
}
|
||||
|
||||
bindsym $mod+d mode "resize"
|
||||
|
||||
bindsym $mod+shift+w [floating title="Webex"] move scratchpad
|
||||
|
||||
for_window [class="KeePassXC"] floating enable
|
||||
for_window [class="KeePassXC"] resize set 1024 768
|
||||
|
||||
exec --no-startup-id "/usr/bin/dunst"
|
||||
exec --no-startup-id "/usr/bin/enpass"
|
||||
exec --no-startup-id "/usr/bin/nm-applet"
|
||||
exec --no-startup-id "/usr/bin/udiskie -t"
|
||||
exec --no-startup-id "/usr/bin/xfce4-power-manager"
|
||||
exec --no-startup-id "solaar -w hide"
|
||||
|
||||
exec_always --no-startup-id "setxkbmap -layout us -variant altgr-intl"
|
||||
|
||||
# fn keys
|
||||
bindsym XF86AudioLowerVolume exec amixer -D pulse sset Master 2%- && pkill -SIGRTMIN+10 i3blocks
|
||||
bindsym XF86AudioRaiseVolume exec amixer -D pulse sset Master 2%+ && pkill -SIGRTMIN+10 i3blocks
|
||||
bindsym XF86AudioMute exec amixer -D pulse sset Master toggle && pkill -SIGRTMIN+10 i3blocks
|
||||
|
||||
# pip3 install spotify-cli-linux --user
|
||||
bindsym XF86AudioStop exec notify-send "$(~/.local/bin/spotifycli --status)" && pkill -SIGRTMIN+11 i3blocks
|
||||
bindsym XF86AudioPlay exec ~/.local/bin/spotifycli --playpause && pkill -SIGRTMIN+11 i3blocks
|
||||
bindsym XF86AudioNext exec ~/.local/bin/spotifycli --next && pkill -SIGRTMIN+11 i3blocks
|
||||
bindsym XF86AudioPrev exec ~/.local/bin/spotifycli --prev && pkill -SIGRTMIN+11 i3blocks
|
||||
|
||||
bindsym Ctrl+Shift+l exec --no-startup-id ~/.config/i3/scripts/i3lock_blur.sh
|
||||
bindsym $mod+q exec ~/.config/i3/scripts/i3_exit.sh
|
||||
|
||||
|
||||
#######
|
||||
#THEME#
|
||||
#######
|
||||
|
||||
# set primary gruvbox colorscheme colors
|
||||
set $white #ffffff
|
||||
set $bg #282828
|
||||
set $gray #ddc7a1
|
||||
set $darkgray #1d2021
|
||||
set $red #ea6962
|
||||
set $green #d8a657
|
||||
set $yellow #dccdab
|
||||
set $blue #7daea3
|
||||
set $purple #d3869b
|
||||
set $aqua #89b482
|
||||
|
||||
# font used by i3 for titles and bars
|
||||
font pango:DejaVuSansM Nerd Font Propo Bold 9
|
||||
|
||||
bar {
|
||||
position top
|
||||
status_command i3blocks
|
||||
tray_padding 5
|
||||
#i3-min-version-check# height 30
|
||||
colors {
|
||||
# bar background color
|
||||
background $bg
|
||||
# text color used for blocks that do not have a color specified.
|
||||
statusline $gray
|
||||
# workspaces section
|
||||
# border backgr. text
|
||||
focused_workspace $aqua $aqua $darkgray
|
||||
inactive_workspace $darkgray $darkgray $gray
|
||||
active_workspace $darkgray $darkgray $gray
|
||||
urgent_workspace $red $red $white
|
||||
}
|
||||
}
|
||||
|
||||
# class border|backgr|text|indicator
|
||||
client.focused $aqua $aqua $darkgray $purple
|
||||
client.focused_inactive $darkgray $darkgray $gray $purple
|
||||
client.unfocused $darkgray $darkgray $gray $purple
|
||||
client.urgent $red $red $white $red
|
||||
|
||||
|
||||
# END BASE.CONFIG
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# BEGIN Timibook.hw.config
|
||||
|
||||
exec --no-startup-id "/usr/bin/blueman-applet"
|
||||
exec_always --no-startup-id "redshift -x; redshift -o -O 4500"
|
||||
exec_always --no-startup-id "xinput set-prop 'TPPS/2 Synaptics TrackPoint' 'libinput Accel Speed' -0.7"
|
||||
# CMD: pkill redshift; redshift -x; redshift -o -O 4500 -m randr:crtc=0
|
||||
|
||||
bindsym $mod+Return exec alacritty -o font.size=12
|
||||
bindsym $mod+r exec --no-startup-id rofi -show drun
|
||||
bindsym $mod+w exec --no-startup-id rofi -show window
|
||||
bindsym $win+P exec ~/.config/i3/scripts/hdmi_setup --toggle
|
||||
bindsym $win+Tab exec ~/.config/i3/scripts/hdmi_setup --switch_mode
|
||||
bindsym XF86MonBrightnessUp exec ~/.config/i3/hw_model/thinkpad/xbacklight --inc 2
|
||||
bindsym XF86MonBrightnessDown exec ~/.config/i3/hw_model/thinkpad/xbacklight --dec 2
|
||||
|
||||
# END Timibook.hw.config
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# BEGIN Dell.hw.config
|
||||
|
||||
bindsym $mod+Return exec /home/jcosmao/.local/bin/alacritty -o font.size=10.5
|
||||
bindsym $mod+r exec --no-startup-id rofi -show drun
|
||||
bindsym $mod+w exec --no-startup-id rofi -show window
|
||||
bindsym XF86MonBrightnessUp exec ~/.config/i3/hw_model/dell/xbacklight --inc 500
|
||||
bindsym XF86MonBrightnessDown exec ~/.config/i3/hw_model/dell/xbacklight --dec 500
|
||||
exec_always --no-startup-id "~/.config/i3/hw_model/dell/touchpad_setup.sh"
|
||||
# CMD: pkill redshift; redshift -x; redshift -o -O 4500 -m randr:crtc=0
|
||||
|
||||
# ex: i3-save-tree --workspace 10 > ~/.config/i3/workspace_10.json
|
||||
# then modify swallow (xprop tools)
|
||||
# i3-msg append_layout ~/.config/i3/workspace_10.json
|
||||
#exec_always --no-startup-id "i3-msg 'workspace 1; append_layout ~/.config/i3/workspace_1.json'"
|
||||
#exec_always --no-startup-id "i3-msg 'workspace 10; append_layout ~/.config/i3/workspace_10.json'"
|
||||
|
||||
# END Dell.hw.config
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# BEGIN NUC8i5BEK.hw.config
|
||||
|
||||
bindsym $mod+Return exec alacritty -o font.size=10.5
|
||||
bindsym $mod+r exec --no-startup-id rofi -show drun
|
||||
bindsym $mod+w exec --no-startup-id rofi -show window
|
||||
|
||||
# END NUC8i5BEK.hw.config
|
||||
|
|
@ -0,0 +1 @@
|
|||
touch $(cat /sys/devices/virtual/dmi/id/product_name).hw.config
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# BEGIN Timibook.hw.config
|
||||
|
||||
exec --no-startup-id "/usr/bin/blueman-applet"
|
||||
exec_always --no-startup-id "redshift -x; redshift -o -O 4500"
|
||||
# CMD: pkill redshift; redshift -x; redshift -o -O 4500 -m randr:crtc=0
|
||||
|
||||
bindsym $mod+Return exec alacritty
|
||||
bindsym $mod+r exec --no-startup-id rofi -show drun
|
||||
bindsym $mod+w exec --no-startup-id rofi -show window
|
||||
bindsym XF86MonBrightnessUp exec /usr/bin/xbacklight -inc 5
|
||||
bindsym XF86MonBrightnessDown exec /usr/bin/xbacklight -dec 5
|
||||
bindsym $win+P exec ~/.config/i3/scripts/hdmi_setup --toggle
|
||||
bindsym $win+Tab exec ~/.config/i3/scripts/hdmi_setup --switch_mode
|
||||
|
||||
# END Timibook.hw.config
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# SETUP from gnome
|
||||
# ❯ xinput list-props 12
|
||||
gnome_setup="
|
||||
libinput Tapping Enabled (284): 1
|
||||
libinput Tapping Enabled Default (285): 0
|
||||
libinput Tapping Drag Enabled (286): 1
|
||||
libinput Tapping Drag Enabled Default (287): 1
|
||||
libinput Tapping Drag Lock Enabled (288): 1
|
||||
libinput Tapping Drag Lock Enabled Default (289): 0
|
||||
libinput Tapping Button Mapping Enabled (290): 1, 0
|
||||
libinput Tapping Button Mapping Default (291): 1, 0
|
||||
libinput Natural Scrolling Enabled (292): 0
|
||||
libinput Natural Scrolling Enabled Default (293): 0
|
||||
libinput Disable While Typing Enabled (294): 1
|
||||
libinput Disable While Typing Enabled Default (295): 1
|
||||
libinput Scroll Methods Available (296): 1, 1, 0
|
||||
libinput Scroll Method Enabled (297): 1, 0, 0
|
||||
libinput Scroll Method Enabled Default (298): 1, 0, 0
|
||||
libinput Accel Speed (299): 0.136691
|
||||
libinput Accel Speed Default (300): 0.000000
|
||||
libinput Left Handed Enabled (301): 0
|
||||
libinput Left Handed Enabled Default (302): 0
|
||||
libinput Send Events Modes Available (269): 1, 1
|
||||
libinput Send Events Mode Enabled (270): 0, 0
|
||||
libinput Send Events Mode Enabled Default (271): 0, 0
|
||||
libinput Horizontal Scroll Enabled (304): 1
|
||||
"
|
||||
|
||||
touchpad_id=$(xinput list | grep Touchpad | grep -Po '(?<=id=)\d+')
|
||||
|
||||
echo "$gnome_setup" | while read line; do
|
||||
name=$(echo "$line" | grep -Po '.*(?= \(\d+\))')
|
||||
value=$(echo "$line" | cut -d':' -f2)
|
||||
if [[ -n "$value" ]]; then
|
||||
xinput set-prop $touchpad_id "$name" $value 2> /dev/null
|
||||
fi
|
||||
done
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Need brightness-udev for non root users to access file
|
||||
|
||||
|
||||
function inc_brightness() {
|
||||
inc=$1
|
||||
current=$(cat /sys/class/backlight/intel_backlight/brightness)
|
||||
echo $((current + inc)) > /sys/class/backlight/intel_backlight/brightness
|
||||
exit
|
||||
}
|
||||
|
||||
function dec_brightness() {
|
||||
dec=$1
|
||||
current=$(cat /sys/class/backlight/intel_backlight/brightness)
|
||||
echo $((current - dec)) > /sys/class/backlight/intel_backlight/brightness
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
function main ()
|
||||
{
|
||||
while [[ $# -ne 0 ]]; do
|
||||
arg="$1"; shift
|
||||
case "$arg" in
|
||||
--inc) val=$1; inc_brightness $val ;;
|
||||
--dec) val=$1; dec_brightness $val ;;
|
||||
* ) [[ $arg =~ \-+.* ]] && echo "$arg unknown"
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
SUBSYSTEM=="backlight", ACTION=="add",
|
||||
RUN+="/bin/chgrp video /sys/class/backlight/amdgpu_bl1/brightness",
|
||||
RUN+="/bin/chmod g+w /sys/class/backlight/amdgpu_bl1/brightness"
|
||||
RUN+="/bin/chgrp video /sys/class/backlight/amdgpu_bl0/brightness",
|
||||
RUN+="/bin/chmod g+w /sys/class/backlight/amdgpu_bl0/brightness"
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
```shell
|
||||
# deps
|
||||
yay -S strace redshift aur/thinkfan xorg-xdpyinfo ffmpeg pavucontrol pulseaudio pulseaudio-alsa mpstat sysstat autofs feh
|
||||
|
||||
# xbacklight
|
||||
sudo 10-xbacklight.rules /etc/udev/rules.d/
|
||||
|
||||
# thinkfan
|
||||
yay -S thinkfan
|
||||
cp thinkfan.service.d/override.conf /etc/systemd/system/thinkfan.service.d/override.conf
|
||||
|
||||
# trackpoint
|
||||
❭ echo -n 200 > /sys/devices/platform/i8042/serio1/sensitivity
|
||||
❭ xinput set-prop "TPPS/2 Synaptics TrackPoint" "libinput Accel Speed" -0.7
|
||||
```
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Set amdgpu powerlevel
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c "echo low > /sys/class/drm/card1/device/power_dpm_force_performance_level"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $(id -u) -ne 0 ]]; then
|
||||
echo "Need to be root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONF=/etc/thinkfan.conf
|
||||
|
||||
echo 'options thinkpad_acpi fan_control=1' > /etc/modprobe.d/99-fancontrol.conf
|
||||
|
||||
echo "
|
||||
# GPU
|
||||
tp_fan /proc/acpi/ibm/fan
|
||||
|
||||
$(find /sys/devices -type f -name 'temp*_input' | while read f; do cat $f > /dev/null && echo hwmon $f;done 2> /dev/null)
|
||||
|
||||
# level temp_min temp_max
|
||||
(0, 0, 42)
|
||||
(1, 40, 47)
|
||||
(2, 45, 52)
|
||||
(3, 50, 57)
|
||||
(4, 55, 62)
|
||||
(5, 60, 77)
|
||||
(7, 73, 93)
|
||||
(127, 85, 32767)
|
||||
" > $CONF
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[Service]
|
||||
# Decrease biasing (up to -b-10) if your fan speed changes too quickly,
|
||||
# Increase biasing (up to -b20) if your fan speed changes too slowly.
|
||||
Environment='THINKFAN_ARGS=-b0'
|
||||
ExecStartPre='/home/ju/.dotfiles/config.X11/i3/hw_model/thinkpad/thinkfan-build-conf.sh'
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Set trackpoint sensitivity
|
||||
After=lightdm.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c "echo -n 200 > /sys/devices/platform/i8042/serio1/sensitivity"
|
||||
# ExecStart=/bin/bash -c "xinput set-prop 'TPPS/2 Synaptics TrackPoint' 'libinput Accel Speed' -0.7"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Need brightness-udev for non root users to access file
|
||||
|
||||
file=$(find -L /sys/class/backlight/ -maxdepth 2 -name brightness 2> /dev/null)
|
||||
|
||||
function inc_brightness() {
|
||||
inc=$1
|
||||
current=$(cat $file)
|
||||
echo $((current + inc)) > $file
|
||||
exit
|
||||
}
|
||||
|
||||
function dec_brightness() {
|
||||
dec=$1
|
||||
current=$(cat $file)
|
||||
echo $((current - dec)) > $file
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
function main ()
|
||||
{
|
||||
while [[ $# -ne 0 ]]; do
|
||||
arg="$1"; shift
|
||||
case "$arg" in
|
||||
--inc) val=$1; inc_brightness $val ;;
|
||||
--dec) val=$1; dec_brightness $val ;;
|
||||
* ) [[ $arg =~ \-+.* ]] && echo "$arg unknown"
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
exec &> /tmp/$(basename $0).log
|
||||
|
||||
action=${1:-reload}
|
||||
|
||||
i3_dir=$( dirname "${BASH_SOURCE[0]}" )
|
||||
i3_config_base="$i3_dir/base.config"
|
||||
hw_name=$(cat /sys/devices/virtual/dmi/id/product_name)
|
||||
i3_family_config="${i3_dir}/hw_model/$hw_name.hw.config"
|
||||
layout=$(autorandr --detected 2>&1 | head -1 2> /dev/null)
|
||||
|
||||
screen_laptop=$(xrandr | grep " connected" | awk '{print $1}' | grep -P '^eDP')
|
||||
screen_hdmi_1=$(xrandr | grep " connected" | awk '{print $1}' | grep -P '^HDMI' | head -n 1)
|
||||
screen_hdmi_2=$(xrandr | grep " connected" | awk '{print $1}' | grep -P '^HDMI' | head -n 2 | tail -1)
|
||||
screen_display_port_1=$(xrandr | grep " connected" | awk '{print $1}' | grep -P '^DP' | head -n 1)
|
||||
screen_display_port_2=$(xrandr | grep " connected" | awk '{print $1}' | grep -P '^DP' | head -n 2 | tail -1)
|
||||
|
||||
if [[ -f "${i3_dir}/i3_layout/${layout}.layout.config" ]]; then
|
||||
i3_layout_config="${i3_dir}/i3_layout/${layout}.layout.config"
|
||||
fi
|
||||
|
||||
# build final i3 config
|
||||
cat "$i3_config_base" \
|
||||
"$i3_family_config" \
|
||||
"$i3_layout_config" > ${i3_dir}/config 2> /dev/null
|
||||
|
||||
min_version=4.22
|
||||
# return 0 if current version is >= min_version
|
||||
(echo $min_version; echo $(i3 -v | sed -re 's/i3 version ([^ ]+).*/\1/')) | sort -CV
|
||||
[[ $? == 0 ]] && sed -i 's/#i3-min-version-check# //' ${i3_dir}/config
|
||||
|
||||
sed -ri "s/<LAYOUT_NAME>/$layout/g" ${i3_dir}/config
|
||||
sed -ri "s/<HDMI_1>/$screen_hdmi_1/g" ${i3_dir}/config
|
||||
sed -ri "s/<HDMI_2>/$screen_hdmi_2/g" ${i3_dir}/config
|
||||
sed -ri "s/<eDP>/$screen_laptop/g" ${i3_dir}/config
|
||||
sed -ri "s/<DP_1>/$screen_display_port_1/g" ${i3_dir}/config
|
||||
sed -ri "s/<DP_2>/$screen_display_port_2/g" ${i3_dir}/config
|
||||
|
||||
# Term font size
|
||||
SCRIPT=$(readlink -f $0)
|
||||
SCRIPTPATH=$(dirname $SCRIPT)
|
||||
bash $SCRIPTPATH/scripts/term_font_size.sh
|
||||
|
||||
setxkbmap -layout us -variant altgr-intl
|
||||
[[ -d ~/.wallpapers ]] && /usr/bin/feh --bg-fill --no-fehbg --randomize ~/.wallpapers/*
|
||||
|
||||
# Then reload/restart i3
|
||||
i3-msg $action
|
||||
|
||||
# exec commands on reload/restart (redshift issue)
|
||||
sleep 0.5
|
||||
cat ${i3_dir}/config | grep "^# CMD:" | sed -e 's/# CMD://g' | bash
|
||||
|
|
@ -0,0 +1 @@
|
|||
<autorandr_name>.layout.config
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# BEGIN home_office.layout.config
|
||||
|
||||
exec_always --no-startup-id "autorandr --skip-options gamma --force <LAYOUT_NAME>"
|
||||
|
||||
workspace 1 output <DP_1>
|
||||
workspace 2 output <DP_1>
|
||||
workspace 3 output <DP_1>
|
||||
workspace 4 output <DP_1>
|
||||
workspace 5 output <DP_1>
|
||||
workspace 6 output <DP_1>
|
||||
workspace 7 output <DP_1>
|
||||
workspace 8 output <DP_1>
|
||||
workspace 9 output <DP_1>
|
||||
workspace 10 output <eDP>
|
||||
workspace 11 output <eDP>
|
||||
workspace 12 output <eDP>
|
||||
|
||||
workspace_auto_back_and_forth no
|
||||
|
||||
# force move
|
||||
exec_always --no-startup-id "i3-msg '[workspace=1] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=2] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=3] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=4] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=5] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=6] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=7] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=8] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=9] move workspace to output <DP_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=10] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=11] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=12] move workspace to output <eDP>'"
|
||||
|
||||
# END home_office.layout.config
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# BEGIN home_office.layout.config
|
||||
|
||||
exec_always --no-startup-id "autorandr --skip-options gamma --force <LAYOUT_NAME>"
|
||||
|
||||
workspace 1 output <HDMI_1>
|
||||
workspace 2 output <HDMI_1>
|
||||
workspace 3 output <HDMI_1>
|
||||
workspace 4 output <HDMI_1>
|
||||
workspace 5 output <HDMI_1>
|
||||
workspace 6 output <HDMI_1>
|
||||
workspace 7 output <HDMI_1>
|
||||
workspace 8 output <HDMI_1>
|
||||
workspace 9 output <HDMI_1>
|
||||
workspace 10 output <eDP>
|
||||
workspace 11 output <eDP>
|
||||
workspace 12 output <eDP>
|
||||
|
||||
workspace_auto_back_and_forth no
|
||||
|
||||
# force move
|
||||
exec_always --no-startup-id "i3-msg '[workspace=1] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=2] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=3] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=4] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=5] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=6] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=7] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=8] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=9] move workspace to output <HDMI_1>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=10] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=11] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=12] move workspace to output <eDP>'"
|
||||
|
||||
# END home_office.layout.config
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# BEGIN laptop.layout.config
|
||||
|
||||
exec_always --no-startup-id "autorandr --skip-options gamma --force <LAYOUT_NAME>"
|
||||
# force all other screen off (autorandr bug..)
|
||||
exec_always --no-startup-id "for screen in $(xrandr | grep connected | cut -d' ' -f1 | grep -v '<eDP>'); do xrandr --output $screen --off; done"
|
||||
|
||||
workspace 1 output <eDP>
|
||||
workspace 2 output <eDP>
|
||||
workspace 3 output <eDP>
|
||||
workspace 4 output <eDP>
|
||||
workspace 5 output <eDP>
|
||||
workspace 6 output <eDP>
|
||||
workspace 7 output <eDP>
|
||||
workspace 8 output <eDP>
|
||||
workspace 9 output <eDP>
|
||||
workspace 10 output <eDP>
|
||||
|
||||
workspace_auto_back_and_forth no
|
||||
|
||||
# force move
|
||||
exec_always --no-startup-id "i3-msg '[workspace=1] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=2] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=3] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=4] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=5] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=6] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=7] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=8] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=9] move workspace to output <eDP>'"
|
||||
exec_always --no-startup-id "i3-msg '[workspace=10] move workspace to output <eDP>'"
|
||||
|
||||
# END
|
||||
|
|
@ -0,0 +1 @@
|
|||
home_office.layout.config
|
||||
|
|
@ -0,0 +1 @@
|
|||
home_office.layout.config
|
||||
|
|
@ -0,0 +1 @@
|
|||
home_office.layout.config
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
pkill firefox
|
||||
|
||||
find ~/.mozilla -name prefs.js | while read pref; do
|
||||
profile=$(dirname $pref)
|
||||
cat $pref | grep -q '^user_pref("toolkit.legacyUserProfileCustomizations.stylesheets'
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
sed 's/user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", false);/user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);/' -i $pref
|
||||
else
|
||||
echo 'user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);' >> $pref
|
||||
fi
|
||||
|
||||
mkdir -p $profile/chrome
|
||||
cat <<EOF > $profile/chrome/userChrome.css
|
||||
#main-window[titlepreface*="[Sidebery]"] #titlebar {visibility: collapse !important;}
|
||||
EOF
|
||||
|
||||
done
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
|
||||
primary=$(xrandr --current | grep primary | awk '{print $1}')
|
||||
hdmi_output="HDMI2"
|
||||
|
||||
function get_state
|
||||
{
|
||||
state=$(xrandr --listactivemonitors | tail -n +2)
|
||||
nb_screen=$(echo "$state" | wc -l)
|
||||
|
||||
if [[ $nb_screen -eq 1 ]]; then
|
||||
if echo "$state" | grep -q $primary; then
|
||||
echo hdmi_off
|
||||
else
|
||||
echo hdmi_only
|
||||
fi
|
||||
elif [[ $nb_screen -eq 2 ]]; then
|
||||
if echo "$state" | grep -Pq "\+0\+0\s+$hdmi_output"; then
|
||||
echo hdmi_mirror
|
||||
else
|
||||
echo hdmi_right
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function hdmi_switch_mode
|
||||
{
|
||||
state=$(get_state)
|
||||
[[ $state == "hdmi_mirror" ]] && hdmi_right && exit
|
||||
[[ $state == "hdmi_right" ]] && hdmi_only && exit
|
||||
[[ $state == "hdmi_only" ]] && hdmi_mirror && exit
|
||||
}
|
||||
|
||||
function hdmi_toggle
|
||||
{
|
||||
state=$(get_state)
|
||||
[[ $state == "hdmi_off" ]] && hdmi_mirror && exit
|
||||
[[ $state != "hdmi_off" ]] && hdmi_off && exit
|
||||
}
|
||||
|
||||
function hdmi_mirror
|
||||
{
|
||||
primary_on
|
||||
xrandr --output $hdmi_output --auto --same-as $primary
|
||||
sound_to_hdmi
|
||||
}
|
||||
|
||||
function hdmi_right
|
||||
{
|
||||
primary_on
|
||||
xrandr --output $hdmi_output --auto --right-of $primary
|
||||
sound_to_hdmi
|
||||
}
|
||||
|
||||
function hdmi_only
|
||||
{
|
||||
hdmi_mirror
|
||||
primary_off
|
||||
sound_to_hdmi
|
||||
}
|
||||
|
||||
function hdmi_off
|
||||
{
|
||||
primary_on
|
||||
xrandr --output $hdmi_output --off
|
||||
reset_sound
|
||||
}
|
||||
|
||||
function primary_off
|
||||
{
|
||||
xrandr --output $primary --off
|
||||
}
|
||||
|
||||
function primary_on
|
||||
{
|
||||
xrandr --output $primary --auto
|
||||
}
|
||||
|
||||
function sound_to_hdmi
|
||||
{
|
||||
hdmi_sound_card=$(pacmd list-cards | grep 'output:' | grep $hdmi_output | head -1 | awk '{print $1}')
|
||||
pactl set-card-profile 0 $hdmi_sound_card
|
||||
pulseaudio --kill
|
||||
}
|
||||
|
||||
function reset_sound
|
||||
{
|
||||
pactl set-card-profile 0 output:analog-stereo
|
||||
pulseaudio --kill
|
||||
}
|
||||
|
||||
function print_help ()
|
||||
{
|
||||
[[ $# -ne 0 ]] && echo "[HELP ] $*"
|
||||
|
||||
echo "
|
||||
$0 [--toggle|--switch_mode|--mirror|--right|--hdmi_only]
|
||||
|
||||
# Require:
|
||||
- xrandr
|
||||
- pulseaudio
|
||||
- configure hdmi output name (xrandr -q)
|
||||
"
|
||||
|
||||
exit
|
||||
}
|
||||
|
||||
function main ()
|
||||
{
|
||||
[[ $# -eq 0 ]] && print_help
|
||||
|
||||
while [[ $# -ne 0 ]]; do
|
||||
arg="$1"; shift
|
||||
case "$arg" in
|
||||
--toggle) hdmi_toggle ;;
|
||||
--switch_mode) hdmi_switch_mode ;;
|
||||
--off) hdmi_off ;;
|
||||
--mirror) hdmi_mirror ;;
|
||||
--right) hdmi_right ;;
|
||||
--hdmi_only) hdmi_only;;
|
||||
--help) print_help ;;
|
||||
* ) [[ $arg =~ \-+.* ]] && print_help "$arg unknown"
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
select=$(
|
||||
echo -e "lock\nlogout\nsuspend\nreboot\nshutdown" | \
|
||||
dmenu -sf '#000000' -sb '#f00060' -i -p "i3 action ?"
|
||||
)
|
||||
|
||||
function lock()
|
||||
{
|
||||
~/.config/i3/scripts/i3lock_blur.sh
|
||||
}
|
||||
|
||||
case "$select" in
|
||||
lock)
|
||||
lock
|
||||
;;
|
||||
logout)
|
||||
loginctl list-sessions -o json | jq -r .[].session | xargs loginctl terminate-session
|
||||
;;
|
||||
suspend)
|
||||
# nmcli radio wifi off && \
|
||||
lock && \
|
||||
systemctl suspend
|
||||
;;
|
||||
reboot)
|
||||
systemctl reboot
|
||||
;;
|
||||
shutdown)
|
||||
systemctl poweroff
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {lock|logout|suspend|reboot|shutdown}"
|
||||
exit 2
|
||||
esac
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
# i3-get-window-criteria - Get criteria for use with i3 config commands
|
||||
|
||||
# To use, run this script, then click on a window.
|
||||
# Output is in the format: [<name>=<value> <name>=<value> ...]
|
||||
|
||||
# Known problem: when WM_NAME is used as fallback for the 'title="<string>"' criterion,
|
||||
# quotes in "<string>" are not escaped properly. This is a problem with the output of `xprop`,
|
||||
# reported upstream: https://bugs.freedesktop.org/show_bug.cgi?id=66807
|
||||
|
||||
PROGNAME=`basename "$0"`
|
||||
|
||||
# Check for xwininfo and xprop
|
||||
for cmd in xwininfo xprop; do
|
||||
if ! which $cmd > /dev/null 2>&1; then
|
||||
echo "$PROGNAME: $cmd: command not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
match_int='[0-9][0-9]*'
|
||||
match_string='".*"'
|
||||
match_qstring='"[^"\\]*(\\.[^"\\]*)*"' # NOTE: Adds 1 backreference
|
||||
|
||||
{
|
||||
# Run xwininfo, get window id
|
||||
window_id=`xwininfo -int | sed -nre "s/^xwininfo: Window id: ($match_int) .*$/\1/p"`
|
||||
echo "id=$window_id"
|
||||
|
||||
# Run xprop, transform its output into i3 criteria. Handle fallback to
|
||||
# WM_NAME when _NET_WM_NAME isn't set
|
||||
xprop -id $window_id |
|
||||
sed -nr \
|
||||
-e "s/^WM_CLASS\(STRING\) = ($match_qstring), ($match_qstring)$/instance=\1\nclass=\3/p" \
|
||||
-e "s/^WM_WINDOW_ROLE\(STRING\) = ($match_qstring)$/window_role=\1/p" \
|
||||
-e "/^WM_NAME\(STRING\) = ($match_string)$/{s//title=\1/; h}" \
|
||||
-e "/^_NET_WM_NAME\(UTF8_STRING\) = ($match_qstring)$/{s//title=\1/; h}" \
|
||||
-e '${g; p}'
|
||||
} | sort | tr "\n" " " | sed -r 's/^(.*) $/[\1]\n/'
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
image_file="/tmp/$(basename $0).png"
|
||||
rm -f $image_file
|
||||
resolution=$(xdpyinfo | grep dimensions | awk '{print $2}')
|
||||
#filters='noise=alls=10,scale=iw*.05:-1,scale=iw*20:-1:flags=neighbor'
|
||||
filters='boxblur=20'
|
||||
|
||||
ffmpeg -y -loglevel 0 -s "$resolution" -f x11grab -i $DISPLAY -vframes 1 -vf "$filters" "$image_file"
|
||||
DISPLAY=${DISPLAY:-:0.0} i3lock -t -i "$image_file"
|
||||
chmod 777 $image_file
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
layout=$(autorandr |& grep detected | awk '{print $1}')
|
||||
|
||||
if [[ $layout == 'laptop' ]]; then
|
||||
echo "Set alacritty font size to '12'"
|
||||
sed -ri "s,^(\s*size:\s*).*,\112," $HOME/.config/alacritty/alacritty.yml
|
||||
else
|
||||
echo "Set alacritty font size to '12'"
|
||||
sed -ri "s,^(\s*size:\s*).*,\112," $HOME/.config/alacritty/alacritty.yml
|
||||
fi
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
#!/bin/bash
|
||||
# Copyright (C) 2012 Stefan Breunig <stefan+measure-net-speed@mathphys.fsk.uni-heidelberg.de>
|
||||
# Copyright (C) 2014 kaueraal
|
||||
# Copyright (C) 2015 Thiago Perrotta <perrotta dot thiago at poli dot ufrj dot br>
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
COLOR='#91c8ed'
|
||||
|
||||
# Get custom IN and OUT labels if provided by command line arguments
|
||||
while [[ $# -gt 1 ]]; do
|
||||
key="$1"
|
||||
case "$key" in
|
||||
-i|--inlabel)
|
||||
INLABEL="$2"
|
||||
shift;;
|
||||
-o|--outlabel)
|
||||
OUTLABEL="$2"
|
||||
shift;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[[ -z $INLABEL ]] && INLABEL="IN "
|
||||
[[ -z $OUTLABEL ]] && OUTLABEL="OUT "
|
||||
|
||||
# Use the provided interface, otherwise the device used for the default route.
|
||||
if [[ -z $INTERFACE ]] && [[ -n $BLOCK_INSTANCE ]]; then
|
||||
INTERFACE=$BLOCK_INSTANCE
|
||||
elif [[ -z $INTERFACE ]]; then
|
||||
INTERFACE=$(ip route | awk '/^default/ { print $5 ; exit }')
|
||||
fi
|
||||
|
||||
# Issue #36 compliant.
|
||||
if ! [ -e "/sys/class/net/${INTERFACE}/operstate" ] || \
|
||||
(! [ "$TREAT_UNKNOWN_AS_UP" = "1" ] &&
|
||||
! [ "`cat /sys/class/net/${INTERFACE}/operstate`" = "up" ])
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# path to store the old results in
|
||||
path="/dev/shm/$(basename $0)-${INTERFACE}"
|
||||
|
||||
# grabbing data for each adapter.
|
||||
read rx < "/sys/class/net/${INTERFACE}/statistics/rx_bytes"
|
||||
read tx < "/sys/class/net/${INTERFACE}/statistics/tx_bytes"
|
||||
|
||||
# get time
|
||||
time=$(date +%s)
|
||||
|
||||
# write current data if file does not exist. Do not exit, this will cause
|
||||
# problems if this file is sourced instead of executed as another process.
|
||||
if ! [[ -f "${path}" ]]; then
|
||||
echo "${time} ${rx} ${tx}" > "${path}"
|
||||
chmod 0666 "${path}"
|
||||
fi
|
||||
|
||||
# read previous state and update data storage
|
||||
read old < "${path}"
|
||||
echo "${time} ${rx} ${tx}" > "${path}"
|
||||
|
||||
# parse old data and calc time passed
|
||||
old=(${old//;/ })
|
||||
time_diff=$(( $time - ${old[0]} ))
|
||||
|
||||
# sanity check: has a positive amount of time passed
|
||||
[[ "${time_diff}" -gt 0 ]] || exit
|
||||
|
||||
# calc bytes transferred, and their rate in byte/s
|
||||
rx_diff=$(( $rx - ${old[1]} ))
|
||||
tx_diff=$(( $tx - ${old[2]} ))
|
||||
rx_rate=$(( $rx_diff / $time_diff ))
|
||||
tx_rate=$(( $tx_diff / $time_diff ))
|
||||
|
||||
# shift by 10 bytes to get KiB/s. If the value is larger than
|
||||
# 1024^2 = 1048576, then display MiB/s instead
|
||||
|
||||
# incoming
|
||||
echo -n "$INLABEL"
|
||||
rx_kib=$(( $rx_rate >> 10 ))
|
||||
if hash bc 2>/dev/null && [[ "$rx_rate" -gt 1048576 ]]; then
|
||||
printf '%3s Mo' "`echo "scale=1; $rx_kib / 1024" | bc`"
|
||||
else
|
||||
printf '%3s Ko' $rx_kib
|
||||
fi
|
||||
|
||||
echo -n " "
|
||||
|
||||
# outgoing
|
||||
echo -n "$OUTLABEL"
|
||||
tx_kib=$(( $tx_rate >> 10 ))
|
||||
if hash bc 2>/dev/null && [[ "$tx_rate" -gt 1048576 ]]; then
|
||||
printf '%3s Mo' "`echo "scale=1; $tx_kib / 1024" | bc`"
|
||||
else
|
||||
printf '%3s Ko' $tx_kib
|
||||
fi
|
||||
|
||||
echo -e "\n..."
|
||||
echo "$COLOR"
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
|
||||
URGENT_VALUE=10
|
||||
|
||||
state=$(acpi 2> /dev/null | grep Battery)
|
||||
if [[ $? -ne 0 ]]; then
|
||||
# No battery
|
||||
exit 0
|
||||
fi
|
||||
|
||||
power=$(echo $state | grep -Po '\d+(?=%)')
|
||||
charging_state=$(echo $state | grep -Po '(Charging|Discharging)')
|
||||
time_remaining=$(echo $state | grep -Po '[\d:]+(?=:\d+ (until charged|remaining))')
|
||||
color=''
|
||||
|
||||
if [[ "${power}" -gt 87 ]]; then
|
||||
icon=" "
|
||||
elif [[ "${power}" -gt 63 ]]; then
|
||||
icon=" "
|
||||
elif [[ "${power}" -gt 38 ]]; then
|
||||
icon=" "
|
||||
elif [[ "${power}" -gt 13 ]]; then
|
||||
icon=" "
|
||||
elif [[ "${power}" -le 13 ]]; then
|
||||
icon=" "
|
||||
else
|
||||
icon=" "
|
||||
fi
|
||||
|
||||
if [[ "${power}" -le "${URGENT_VALUE}" ]]; then
|
||||
color='#ff9980'
|
||||
fi
|
||||
|
||||
if [[ "${charging_state}" = "Discharging" ]]; then
|
||||
echo "${icon} ${power}% |$time_remaining|"
|
||||
echo "${icon} ${power}%"
|
||||
[[ -n $color ]] && echo $color
|
||||
else
|
||||
[[ $power -eq 100 ]] && echo " ${power}%" || \
|
||||
echo " ${power}% |$time_remaining|"
|
||||
echo " ${power}%"
|
||||
fi
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#!/bin/bash
|
||||
# vim: ft=sh
|
||||
|
||||
# rofi-calendar: A pop-up calendar for i3blocks.
|
||||
# Requirements:
|
||||
# - rofi (oxide theme)
|
||||
# - i3blocks
|
||||
# - bash
|
||||
# - cal
|
||||
# - sed
|
||||
|
||||
full_date=$(date '+%-Y-%0m-%_d|%a, %0d %b %0H:%0M|%B')
|
||||
year_number=${full_date:0:4}
|
||||
month_number=${full_date:5:2}
|
||||
day_number=${full_date:8:2}
|
||||
|
||||
cal_command() {
|
||||
ncal -Shb "$month_number" "$year_number" 2> /dev/null || \
|
||||
cal -S "$month_number" "$year_number" 2> /dev/null | sed '1d;s/ *$//g;/^$/d'
|
||||
}
|
||||
|
||||
custom_month() {
|
||||
day_number='Null'
|
||||
the_date=$(date -d "$year_number-$month_number-01" '+%B %-Y')
|
||||
}
|
||||
|
||||
counts_cal_lines() {
|
||||
cal_lines=$(cal_command | wc -l)
|
||||
}
|
||||
|
||||
case "$BLOCK_BUTTON" in
|
||||
1)
|
||||
# Left-click: Current month
|
||||
the_date="${full_date:11:7} ${full_date:29}"
|
||||
;;
|
||||
2)
|
||||
# Middle-click: Previous month
|
||||
((month_number == 1)) && month_number=12 && year_number=$((year_number - 1)) || month_number=$((month_number - 1))
|
||||
custom_month
|
||||
;;
|
||||
3)
|
||||
# Right-click: Next month
|
||||
((month_number == 12)) && month_number=1 && year_number=$((year_number + 1)) || month_number=$((month_number + 1))
|
||||
custom_month
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$BLOCK_BUTTON" in
|
||||
1|2|3)
|
||||
counts_cal_lines
|
||||
cal_command \
|
||||
| sed "s#^#<span color='\#f17171'>#g;s#.#&</span>#24" \
|
||||
| sed "s#\b${day_number// /}\b#<span bgcolor='\#2b83a6' color='\#ffffff'>${day_number// /}</span>#" \
|
||||
| rofi \
|
||||
-dmenu \
|
||||
-lines "$cal_lines" \
|
||||
-font 'Monospace 11' \
|
||||
-location '3' \
|
||||
-xoffset '-50' \
|
||||
-yoffset '35' \
|
||||
-theme-str 'configuration { show-icons: false; }' \
|
||||
-theme-str 'window { fullscreen: false; width: 220px; height: 200px; } inputbar { children: [ prompt ]; } listview { scrollbar: false; }' \
|
||||
-theme-str 'element normal.normal, element selected.normal, element alternate.normal { background-color: #212121; text-color: #c4cad4; }' \
|
||||
-theme-str 'element normal.active, element selected.active, element alternate.active { background-color: #363636; text-color: #f9f9f9; }' \
|
||||
-p "$the_date" \
|
||||
-a '0' \
|
||||
-no-custom \
|
||||
-markup-rows &> /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo " ${full_date:11:17} "
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright 2014 Pierre Mavro <deimos@deimos.fr>
|
||||
# Copyright 2014 Vivien Didelot <vivien@didelot.org>
|
||||
# Copyright 2014 Andreas Guldstrand <andreas.guldstrand@gmail.com>
|
||||
#
|
||||
# Licensed under the terms of the GNU GPL v3, or any later version.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
use Getopt::Long;
|
||||
|
||||
# default values
|
||||
my $t_warn = $ENV{T_WARN} || 50;
|
||||
my $t_crit = $ENV{T_CRIT} || 80;
|
||||
my $cpu_usage = -1;
|
||||
my $decimals = $ENV{DECIMALS} || 2;
|
||||
my $label = $ENV{LABEL} || "";
|
||||
|
||||
sub help {
|
||||
print "Usage: cpu_usage [-w <warning>] [-c <critical>] [-d <decimals>]\n";
|
||||
print "-w <percent>: warning threshold to become yellow\n";
|
||||
print "-c <percent>: critical threshold to become red\n";
|
||||
print "-d <decimals>: Use <decimals> decimals for percentage (default is $decimals) \n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
GetOptions("help|h" => \&help,
|
||||
"w=i" => \$t_warn,
|
||||
"c=i" => \$t_crit,
|
||||
"d=i" => \$decimals,
|
||||
);
|
||||
|
||||
# Get CPU usage
|
||||
$ENV{LC_ALL}="en_US"; # if mpstat is not run under en_US locale, things may break, so make sure it is
|
||||
open (MPSTAT, 'mpstat 1 1 |') or die;
|
||||
while (<MPSTAT>) {
|
||||
if (/^.*\s+(\d+\.\d+)[\s\x00]?$/) {
|
||||
$cpu_usage = 100 - $1; # 100% - %idle
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(MPSTAT);
|
||||
|
||||
$cpu_usage eq -1 and die 'Can\'t find CPU information';
|
||||
|
||||
# Print short_text, full_text
|
||||
print "${label}";
|
||||
printf "%3.${decimals}f%%\n", $cpu_usage;
|
||||
print "${label}";
|
||||
printf "%3.${decimals}f%%\n", $cpu_usage;
|
||||
|
||||
# Print color, if needed
|
||||
if ($cpu_usage >= $t_crit) {
|
||||
print "#ff9980\n";
|
||||
} elsif ($cpu_usage >= $t_warn) {
|
||||
print "#fffc80\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
label = ''
|
||||
color_up = '#9ec600'
|
||||
color_down = '#676767'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output = subprocess.check_output(
|
||||
"ip -br -j addr show",
|
||||
shell=True
|
||||
)
|
||||
json_str = output.decode('utf8')
|
||||
ifaces = json.loads(json_str)
|
||||
|
||||
ethernet = list(filter(lambda x: x['ifname'].startswith('e'),
|
||||
ifaces))
|
||||
|
||||
ethernet_up = list(filter(lambda x: x['operstate'] == 'UP',
|
||||
ethernet))
|
||||
|
||||
if not ethernet:
|
||||
sys.exit(0)
|
||||
|
||||
eth = None
|
||||
if not ethernet_up:
|
||||
eth = ethernet.pop()
|
||||
else:
|
||||
eth = ethernet_up.pop()
|
||||
|
||||
print(label)
|
||||
print(label)
|
||||
if eth['operstate'] == 'DOWN':
|
||||
print(color_down)
|
||||
else:
|
||||
print(color_up)
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
iface_type = os.environ.get('BLOCK_INSTANCE', 'ethernet')
|
||||
label = ''
|
||||
color_up = '#B8A391'
|
||||
color_down = '#676767'
|
||||
|
||||
|
||||
def _get_first_ifname(ifaces, iface_type=iface_type):
|
||||
|
||||
iface_up = None
|
||||
iface_first = None
|
||||
|
||||
for iface in ifaces:
|
||||
if iface_type == 'ethernet' and \
|
||||
iface['ifname'].startswith('e'):
|
||||
iface_first = iface if not iface_first else None
|
||||
iface_up = iface if iface['operstate'] == 'UP' else None
|
||||
|
||||
elif iface_type == 'wireless' and \
|
||||
iface['ifname'].startswith('wl'):
|
||||
iface_first = iface if not iface_first else None
|
||||
iface_up = iface if iface['operstate'] == 'UP' else None
|
||||
|
||||
if iface_up:
|
||||
return iface_up
|
||||
else:
|
||||
return iface_first
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output = subprocess.check_output(
|
||||
"ip -br -j addr show",
|
||||
shell=True
|
||||
)
|
||||
json_str = output.decode('utf8')
|
||||
ifaces = json.loads(json_str)
|
||||
|
||||
first = _get_first_ifname(ifaces, iface_type)
|
||||
|
||||
if first:
|
||||
try:
|
||||
print('{} {}'.format(label, first['addr_info'][0]['local']))
|
||||
print(label)
|
||||
print(color_up)
|
||||
except Exception:
|
||||
print('{} ip'.format(label))
|
||||
print(label)
|
||||
print(color_down)
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
TYPE="${BLOCK_INSTANCE:-mem}"
|
||||
|
||||
awk -v type=$TYPE '
|
||||
/^MemTotal:/ {
|
||||
mem_total=$2
|
||||
}
|
||||
/^MemFree:/ {
|
||||
mem_free=$2
|
||||
}
|
||||
/^Buffers:/ {
|
||||
mem_free+=$2
|
||||
}
|
||||
/^Cached:/ {
|
||||
mem_free+=$2
|
||||
}
|
||||
/^SwapTotal:/ {
|
||||
swap_total=$2
|
||||
}
|
||||
/^SwapFree:/ {
|
||||
swap_free=$2
|
||||
}
|
||||
END {
|
||||
if (type == "swap") {
|
||||
free=swap_free/1024/1024
|
||||
used=(swap_total-swap_free)/1024/1024
|
||||
total=swap_total/1024/1024
|
||||
} else {
|
||||
free=mem_free/1024/1024
|
||||
used=(mem_total-mem_free)/1024/1024
|
||||
total=mem_total/1024/1024
|
||||
}
|
||||
|
||||
pct=0
|
||||
if (total > 0) {
|
||||
pct=used/total*100
|
||||
}
|
||||
|
||||
# full text
|
||||
printf("%3.f%%\n", pct)
|
||||
|
||||
# short text
|
||||
printf("%3.f%%\n", pct)
|
||||
|
||||
# color
|
||||
if (pct > 90) {
|
||||
print("#ff9980")
|
||||
} else if (pct > 80) {
|
||||
print("#ffdf80")
|
||||
} else if (pct > 70) {
|
||||
print("#fffc80")
|
||||
}
|
||||
}
|
||||
' /proc/meminfo
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# pip3 install spotify-cli-linux dbus-python
|
||||
def get_spotify_status():
|
||||
artist_song = None
|
||||
status = None
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
"spotifycli --status 2> /dev/null",
|
||||
shell=True
|
||||
)
|
||||
parse = re.findall(r"^(.*) - (.*)", output.decode('utf-8'))
|
||||
LOG.debug(parse)
|
||||
artist_song = parse[0]
|
||||
|
||||
output = subprocess.check_output(
|
||||
"spotifycli --playbackstatus 2> /dev/null",
|
||||
shell=True
|
||||
).decode('utf-8').strip()
|
||||
|
||||
if output == u"▮▮":
|
||||
status = 'pause'
|
||||
elif output == u"▶":
|
||||
status = 'play'
|
||||
else:
|
||||
status = None
|
||||
|
||||
except Exception as e:
|
||||
LOG.exception(e)
|
||||
LOG.info("Spotify is not running")
|
||||
|
||||
return artist_song, status
|
||||
|
||||
|
||||
def read_line():
|
||||
""" Interrupted respecting reader for stdin. """
|
||||
# try reading a line, removing any extra whitespace
|
||||
try:
|
||||
line = sys.stdin.readline().strip()
|
||||
# i3status sends EOF, or an empty line
|
||||
if not line:
|
||||
sys.exit(3)
|
||||
return line
|
||||
# exit on ctrl-c
|
||||
except KeyboardInterrupt:
|
||||
sys.exit()
|
||||
|
||||
|
||||
def print_line(message):
|
||||
""" Non-buffered printing to stdout. """
|
||||
sys.stdout.write(message + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
spotify_status, status = get_spotify_status()
|
||||
LOG.debug("spotify: {}, status: {}".format(spotify_status, status))
|
||||
|
||||
if spotify_status:
|
||||
artist = spotify_status[0]
|
||||
song = spotify_status[1]
|
||||
color = '#9ec600'
|
||||
if status == 'pause':
|
||||
color = '#676767'
|
||||
|
||||
# long
|
||||
# short
|
||||
# color
|
||||
print(' %s - %s' % (artist, song))
|
||||
print(' %s - %s' % (artist, song))
|
||||
print(color)
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash
|
||||
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
|
||||
# Copyright (C) 2014 Alexander Keller <github@nycroth.com>
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
# The second parameter overrides the mixer selection
|
||||
# For PulseAudio users, eventually use "pulse"
|
||||
# For Jack/Jack2 users, use "jackplug"
|
||||
# For ALSA users, you may use "default" for your primary card
|
||||
# or you may use hw:# where # is the number of the card desired
|
||||
if [[ -z "$MIXER" ]] ; then
|
||||
MIXER="default"
|
||||
if command -v pulseaudio >/dev/null 2>&1 && pulseaudio --check ; then
|
||||
# pulseaudio is running, but not all installations use "pulse"
|
||||
if amixer -D pulse info >/dev/null 2>&1 ; then
|
||||
MIXER="pulse"
|
||||
fi
|
||||
fi
|
||||
[ -n "$(lsmod | grep jack)" ] && MIXER="jackplug"
|
||||
MIXER="${2:-$MIXER}"
|
||||
fi
|
||||
|
||||
# The instance option sets the control to report and configure
|
||||
# This defaults to the first control of your selected mixer
|
||||
# For a list of the available, use `amixer -D $Your_Mixer scontrols`
|
||||
if [[ -z "$SCONTROL" ]] ; then
|
||||
SCONTROL="${BLOCK_INSTANCE:-$(amixer -D $MIXER scontrols |
|
||||
sed -n "s/Simple mixer control '\([^']*\)',0/\1/p" |
|
||||
head -n1
|
||||
)}"
|
||||
fi
|
||||
|
||||
# The first parameter sets the step to change the volume by (and units to display)
|
||||
# This may be in in % or dB (eg. 5% or 3dB)
|
||||
if [[ -z "$STEP" ]] ; then
|
||||
STEP="${1:-5%}"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
capability() { # Return "Capture" if the device is a capture device
|
||||
amixer -D $MIXER get $SCONTROL |
|
||||
sed -n "s/ Capabilities:.*cvolume.*/Capture/p"
|
||||
}
|
||||
|
||||
volume() {
|
||||
amixer -D $MIXER get $SCONTROL $(capability)
|
||||
}
|
||||
|
||||
format() {
|
||||
perl_filter='if (/.*\[(\d+%)\] (\[(-?\d+.\d+dB)\] )?\[(on|off)\]/)'
|
||||
perl_filter+='{CORE::say $4 eq "off" ? " MUTE" : " '
|
||||
# If dB was selected, print that instead
|
||||
perl_filter+=$([[ $STEP = *dB ]] && echo '$3' || echo '$1')
|
||||
perl_filter+='"; exit}'
|
||||
perl -ne "$perl_filter"
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
case $BLOCK_BUTTON in
|
||||
3) amixer -q -D $MIXER sset $SCONTROL $(capability) toggle ;; # right click, mute/unmute
|
||||
4) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}+ unmute ;; # scroll up, increase
|
||||
5) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}- unmute ;; # scroll down, decrease
|
||||
esac
|
||||
|
||||
volume | format
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
label=''
|
||||
color_up='#9ec600'
|
||||
color_down='#676767'
|
||||
|
||||
echo $label
|
||||
echo $label
|
||||
|
||||
function wireguard_count {
|
||||
ip --json link show | jq -r '.[] | select(.ifname | test("^wg")).ifname' | wc -l
|
||||
}
|
||||
|
||||
if [[ -f /var/run/vpnc.pid || -n $(pidof nm-vpnc-service) || $(wireguard_count) > 0 ]]; then
|
||||
echo $color_up
|
||||
else
|
||||
echo $color_down
|
||||
fi
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
label = ' '
|
||||
color_good = '#c0ff80'
|
||||
color_medium = '#fffc80'
|
||||
color_low = '#ffdf80'
|
||||
color_bad = '#ff9980'
|
||||
color_down = '#676767'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output = subprocess.check_output(
|
||||
"ip -br -j addr show",
|
||||
shell=True
|
||||
)
|
||||
json_str = output.decode('utf8')
|
||||
ifaces = json.loads(json_str)
|
||||
|
||||
first = None
|
||||
for iface in ifaces:
|
||||
if iface['ifname'].startswith('wl'):
|
||||
first = iface
|
||||
|
||||
if not first:
|
||||
sys.exit(0)
|
||||
|
||||
if first['operstate'] == 'DOWN':
|
||||
print(label)
|
||||
print(label)
|
||||
print(color_down)
|
||||
sys.exit(0)
|
||||
|
||||
output = subprocess.check_output(
|
||||
'iwconfig {} | grep -Po \'(?<=ESSID:")[^"]*\''.format(first['ifname']),
|
||||
shell=True
|
||||
)
|
||||
apname = output.decode('utf8').strip()
|
||||
|
||||
output = subprocess.check_output(
|
||||
'iwconfig {} | grep -Po "(?<=Link Quality=)\d+"'.format(first['ifname']),
|
||||
shell=True
|
||||
)
|
||||
link_quality = output.decode('utf8').strip()
|
||||
power = int(link_quality) * 100 / 70
|
||||
|
||||
if power >= 80:
|
||||
color = color_good
|
||||
elif power >= 60:
|
||||
color = color_medium
|
||||
elif power >= 40:
|
||||
color = color_low
|
||||
else:
|
||||
color = color_bad
|
||||
|
||||
print('{} {} |{}%|'.format(label, apname, int(power)))
|
||||
print(label)
|
||||
print(color)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# vim: ft=cfg
|
||||
|
||||
command=~/.config/i3blocks/blocks/$BLOCK_NAME
|
||||
separator_block_width=30
|
||||
markup=none
|
||||
|
||||
[spotify]
|
||||
interval=15
|
||||
signal=11
|
||||
|
||||
# Network
|
||||
|
||||
# [bandwidth]
|
||||
# command=~/.config/i3blocks/blocks/$BLOCK_NAME -o ' ' -i ' '
|
||||
# interval=5
|
||||
|
||||
[vpn]
|
||||
interval=5
|
||||
|
||||
[ethernet]
|
||||
interval=10
|
||||
separator=false
|
||||
separator_block_width=10
|
||||
|
||||
[ip]
|
||||
instance=ethernet
|
||||
interval=10
|
||||
|
||||
[wifi]
|
||||
interval=10
|
||||
separator=false
|
||||
separator_block_width=10
|
||||
|
||||
[ip]
|
||||
instance=wireless
|
||||
interval=10
|
||||
|
||||
# Monitoring
|
||||
|
||||
# require sysstat
|
||||
[cpu_usage]
|
||||
label=
|
||||
command=~/.config/i3blocks/blocks/$BLOCK_NAME -d 0
|
||||
interval=10
|
||||
|
||||
[memory]
|
||||
label=
|
||||
interval=30
|
||||
|
||||
[disk]
|
||||
label=
|
||||
command=echo " /: $(df -h -l --output='avail' / | grep -E -o '[0-9]+(G|M)') /home: $(df -h -l --output='avail' /home | grep -E -o '[0-9]+(G|M)')"
|
||||
interval=30
|
||||
|
||||
# Common
|
||||
|
||||
[volume]
|
||||
label=
|
||||
interval=10
|
||||
signal=10
|
||||
|
||||
[battery]
|
||||
interval=10
|
||||
|
||||
[utc_hour]
|
||||
label=
|
||||
command=echo " $(date -u '+%0H:%0M')"
|
||||
interval=5
|
||||
|
||||
[calendar]
|
||||
label=
|
||||
interval=5
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
# vim: ft=cfg
|
||||
|
||||
command=~/.config/i3blocks/blocks/$BLOCK_NAME
|
||||
separator_block_width=30
|
||||
markup=none
|
||||
|
||||
[spotify]
|
||||
interval=15
|
||||
signal=11
|
||||
|
||||
# Network
|
||||
|
||||
# [bandwidth]
|
||||
# command=~/.config/i3blocks/blocks/$BLOCK_NAME -o ' ' -i ' '
|
||||
# interval=5
|
||||
|
||||
[vpn]
|
||||
interval=5
|
||||
|
||||
[ethernet]
|
||||
interval=10
|
||||
separator=false
|
||||
separator_block_width=10
|
||||
|
||||
[ip]
|
||||
instance=ethernet
|
||||
interval=10
|
||||
|
||||
[wifi]
|
||||
interval=10
|
||||
separator=false
|
||||
separator_block_width=10
|
||||
|
||||
[ip]
|
||||
instance=wireless
|
||||
interval=10
|
||||
|
||||
# Monitoring
|
||||
|
||||
# require sysstat
|
||||
[cpu_usage]
|
||||
label=
|
||||
command=~/.config/i3blocks/blocks/$BLOCK_NAME -d 0
|
||||
interval=10
|
||||
separator=false
|
||||
separator_block_width=10
|
||||
|
||||
[memory]
|
||||
label=
|
||||
interval=30
|
||||
|
||||
[disk]
|
||||
label=
|
||||
command=echo " /: $(df -h -l --output='avail' / | grep -E -o '[0-9]+(G|M)') /home: $(df -h -l --output='avail' /home | grep -E -o '[0-9]+(G|M)')"
|
||||
interval=30
|
||||
|
||||
# Common
|
||||
|
||||
[volume]
|
||||
label=
|
||||
interval=10
|
||||
signal=10
|
||||
|
||||
[battery]
|
||||
interval=10
|
||||
|
||||
[utc_hour]
|
||||
label=
|
||||
command=echo " $(date -u '+%0H:%0M')"
|
||||
interval=5
|
||||
|
||||
[canada_hour]
|
||||
label=
|
||||
command=echo " $(TZ=America/Montreal date '+%0H:%0M')"
|
||||
interval=5
|
||||
|
||||
[calendar]
|
||||
label=
|
||||
interval=5
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# i3status configuration file.
|
||||
# see "man i3status" for documentation.
|
||||
|
||||
# It is important that this file is edited as UTF-8.
|
||||
# The following line should contain a sharp s:
|
||||
# ß
|
||||
# If the above line is not correctly displayed, fix your editor first!
|
||||
|
||||
general {
|
||||
output_format = "i3bar"
|
||||
colors = true
|
||||
interval = 5
|
||||
color_good = "#A5DF00"
|
||||
color_bad = "#6E6E6E"
|
||||
color_degraded = "#FF4000"
|
||||
}
|
||||
|
||||
#order += "ipv6"
|
||||
#order += "run_watch DHCP"
|
||||
order += "run_watch VPN"
|
||||
order += "ethernet _first_"
|
||||
order += "wireless _first_"
|
||||
order += "load"
|
||||
order += "disk /"
|
||||
order += "battery all"
|
||||
order += "volume master"
|
||||
order += "tztime local"
|
||||
|
||||
wireless _first_ {
|
||||
format_up = " %essid (%quality) %ip "
|
||||
format_down = " "
|
||||
}
|
||||
|
||||
ethernet _first_ {
|
||||
format_up = " %ip (%speed) "
|
||||
format_down = " "
|
||||
}
|
||||
|
||||
battery all {
|
||||
format = " %status %percentage (%remaining) "
|
||||
last_full_capacity = true
|
||||
integer_battery_capacity = true
|
||||
status_chr = " "
|
||||
status_bat = " "
|
||||
status_full = " "
|
||||
threshold_type = percentage
|
||||
low_threshold = 10
|
||||
}
|
||||
|
||||
run_watch DHCP {
|
||||
pidfile = "/var/run/dhclient*.pid"
|
||||
format_down = " dhcp "
|
||||
}
|
||||
|
||||
run_watch VPN {
|
||||
pidfile = "/var/run/vpnc.pid"
|
||||
format = " "
|
||||
}
|
||||
|
||||
tztime local {
|
||||
format = " %d.%m.%Y %H:%M "
|
||||
}
|
||||
|
||||
load {
|
||||
format = " %1min %5min "
|
||||
}
|
||||
|
||||
disk "/" {
|
||||
format = " %avail "
|
||||
}
|
||||
|
||||
volume master {
|
||||
format = " %volume "
|
||||
device = "default"
|
||||
mixer = "Master"
|
||||
mixer_idx = 0
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* Rofi config file */
|
||||
configuration {
|
||||
font: "Source Sans Pro 12";
|
||||
show-icons: true;
|
||||
display-window: "Window";
|
||||
display-drun: "Search";
|
||||
}
|
||||
|
||||
@theme "oxide"
|
||||
|
||||
listview {
|
||||
lines: 12;
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* Oxide Color theme
|
||||
* Author: Diki Ananta <diki1aap@gmail.com>
|
||||
* Repository: https://github.com/dikiaap/dotfiles
|
||||
* License: MIT
|
||||
**/
|
||||
* {
|
||||
selected-normal-foreground: var(lightfg);
|
||||
foreground: rgba ( 196, 202, 212, 100 % );
|
||||
normal-foreground: var(foreground);
|
||||
alternate-normal-background: rgba ( 42, 42, 42, 100 % );
|
||||
red: rgba ( 194, 65, 65, 100 % );
|
||||
selected-urgent-foreground: var(lightfg);
|
||||
blue: rgba ( 43, 131, 166, 100 % );
|
||||
urgent-foreground: var(lightfg);
|
||||
alternate-urgent-background: var(red);
|
||||
active-foreground: var(lightfg);
|
||||
lightbg: var(foreground);
|
||||
selected-active-foreground: var(lightfg);
|
||||
alternate-active-background: var(blue);
|
||||
background: rgba ( 33, 33, 33, 100 % );
|
||||
alternate-normal-foreground: var(foreground);
|
||||
normal-background: var(background);
|
||||
lightfg: rgba ( 249, 249, 249, 100 % );
|
||||
selected-normal-background: rgba ( 90, 90, 90, 100 % );
|
||||
separatorcolor: rgba ( 183, 183, 183, 100 % );
|
||||
spacing: 2;
|
||||
border-color: var(foreground);
|
||||
urgent-background: var(red);
|
||||
alternate-active-foreground: var(active-foreground);
|
||||
alternate-urgent-foreground: var(urgent-foreground);
|
||||
background-color: transparent;
|
||||
selected-urgent-background: rgba ( 214, 78, 78, 100 % );
|
||||
active-background: var(blue);
|
||||
selected-active-background: rgba ( 39, 141, 182, 100 % );
|
||||
}
|
||||
element {
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
spacing: 4px;
|
||||
padding: 1px;
|
||||
}
|
||||
element normal.normal {
|
||||
background-color: var(normal-background);
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
element normal.urgent {
|
||||
background-color: var(urgent-background);
|
||||
text-color: var(urgent-foreground);
|
||||
}
|
||||
element normal.active {
|
||||
background-color: var(active-background);
|
||||
text-color: var(active-foreground);
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
element selected.urgent {
|
||||
background-color: var(selected-urgent-background);
|
||||
text-color: var(selected-urgent-foreground);
|
||||
}
|
||||
element selected.active {
|
||||
background-color: var(selected-active-background);
|
||||
text-color: var(selected-active-foreground);
|
||||
}
|
||||
element alternate.normal {
|
||||
background-color: var(alternate-normal-background);
|
||||
text-color: var(alternate-normal-foreground);
|
||||
}
|
||||
element alternate.urgent {
|
||||
background-color: var(alternate-urgent-background);
|
||||
text-color: var(alternate-urgent-foreground);
|
||||
}
|
||||
element alternate.active {
|
||||
background-color: var(alternate-active-background);
|
||||
text-color: var(alternate-active-foreground);
|
||||
}
|
||||
element-text {
|
||||
background-color: transparent;
|
||||
highlight: inherit;
|
||||
cursor: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
element-icon {
|
||||
background-color: transparent;
|
||||
size: 21px;
|
||||
cursor: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
window {
|
||||
background-color: var(background);
|
||||
border: 0;
|
||||
padding: 8;
|
||||
}
|
||||
mainbox {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
message {
|
||||
border: 2px dash 0px 0px;
|
||||
border-color: var(separatorcolor);
|
||||
padding: 1px;
|
||||
}
|
||||
textbox {
|
||||
text-color: var(foreground);
|
||||
}
|
||||
listview {
|
||||
fixed-height: 0;
|
||||
border: 0;
|
||||
border-color: var(separatorcolor);
|
||||
spacing: 2px;
|
||||
scrollbar: true;
|
||||
padding: 2px 0px 0px;
|
||||
}
|
||||
scrollbar {
|
||||
width: 4px;
|
||||
border: 0;
|
||||
handle-color: rgba ( 85, 85, 85, 100 % );
|
||||
handle-width: 8px;
|
||||
padding: 0;
|
||||
}
|
||||
sidebar {
|
||||
border: 2px dash 0px 0px;
|
||||
border-color: var(separatorcolor);
|
||||
}
|
||||
button {
|
||||
cursor: pointer;
|
||||
spacing: 0;
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
button selected {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
num-filtered-rows {
|
||||
expand: false;
|
||||
text-color: rgba ( 128, 128, 128, 100 % );
|
||||
}
|
||||
num-rows {
|
||||
expand: false;
|
||||
text-color: rgba ( 128, 128, 128, 100 % );
|
||||
}
|
||||
textbox-num-sep {
|
||||
expand: false;
|
||||
str: "/";
|
||||
text-color: rgba ( 128, 128, 128, 100 % );
|
||||
}
|
||||
inputbar {
|
||||
spacing: 0px;
|
||||
text-color: var(normal-foreground);
|
||||
padding: 1px;
|
||||
children: [ "prompt","textbox-prompt-colon","entry","overlay","case-indicator" ];
|
||||
}
|
||||
case-indicator {
|
||||
spacing: 0;
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
entry {
|
||||
placeholder: "";
|
||||
cursor: text;
|
||||
spacing: 0;
|
||||
text-color: var(normal-foreground);
|
||||
placeholder-color: rgba ( 128, 128, 128, 100 % );
|
||||
}
|
||||
prompt {
|
||||
spacing: 0;
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
textbox-prompt-colon {
|
||||
expand: false;
|
||||
str: ":";
|
||||
margin: 0px 0.3000em 0.0000em 0.0000em;
|
||||
text-color: inherit;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<channel name="xfce4-session" version="1.0">
|
||||
<property name="general" type="empty">
|
||||
<property name="LockCommand" type="string" value="lockscreen"/>
|
||||
</property>
|
||||
<property name="shutdown" type="empty">
|
||||
<property name="LockScreen" type="bool" value="true"/>
|
||||
</property>
|
||||
</channel>
|
||||
|
|
@ -0,0 +1,625 @@
|
|||
---
|
||||
version: 2
|
||||
root-markers:
|
||||
- RCS/
|
||||
- SCCS/
|
||||
- CVS/
|
||||
- .git/
|
||||
- .svn/
|
||||
- .hg/
|
||||
- .bzr/
|
||||
- _darcs/
|
||||
- .git
|
||||
# command define
|
||||
commands:
|
||||
- title: Reload
|
||||
command: :reload-config
|
||||
|
||||
- title: Editor (notepad)
|
||||
os: windows
|
||||
command: notepad
|
||||
arguments:
|
||||
- '${FILENAME}'
|
||||
- title: Editor (gedit)
|
||||
os: linux
|
||||
command: gedit
|
||||
# Linux no method generic GUI editor open
|
||||
arguments:
|
||||
- '${FILENAME}'
|
||||
- title: Editor (default)
|
||||
os: darwin
|
||||
command: open
|
||||
arguments:
|
||||
- '-e'
|
||||
- '${FILENAME}'
|
||||
|
||||
- title: Filer (explorer)
|
||||
os: windows
|
||||
command: cmd
|
||||
arguments:
|
||||
- '/c'
|
||||
- 'explorer /select,${FILENAME}'
|
||||
- title: Filer (Finder)
|
||||
os: darwin
|
||||
# Linux no method generic filer open
|
||||
command: open
|
||||
arguments:
|
||||
- '-R'
|
||||
- '${FILENAME}'
|
||||
|
||||
- title: Browser (default)
|
||||
os: darwin
|
||||
# Windows no method generic browser open
|
||||
# Linux no method generic browser open
|
||||
command: open
|
||||
arguments:
|
||||
- '-a'
|
||||
- 'Safari'
|
||||
- '${FILENAME}'
|
||||
|
||||
- title: Open (system default)
|
||||
os: windows
|
||||
command: rundll32
|
||||
arguments:
|
||||
- 'url.dll,FileProtocolHandler'
|
||||
- '${FILENAME}'
|
||||
- title: Open (system default)
|
||||
os: linux
|
||||
command: xdg-open
|
||||
arguments:
|
||||
- '${FILENAME}'
|
||||
- title: Open (system default)
|
||||
os: darwin
|
||||
command: open
|
||||
arguments:
|
||||
- '${FILENAME}'
|
||||
|
||||
# linter,formatter setting
|
||||
tools:
|
||||
cppcheck-lint: &cppcheck-lint
|
||||
prefix: cppcheck
|
||||
lint-command: 'cppcheck --quiet --force --enable=style --error-exitcode=1 ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m'
|
||||
root-markers:
|
||||
- compile_commands.json
|
||||
|
||||
vale-lint: &vale-lint
|
||||
prefix: vale
|
||||
lint-command: 'vale --relative --output line ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-ignore-exit-code: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c:%*[^:]:%m'
|
||||
|
||||
redpen-lint-core: &redpen-lint-core
|
||||
prefix: redpen
|
||||
lint-command: 'redpen -l 9999 -r plain ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-ignore-exit-code: true
|
||||
lint-formats:
|
||||
- '%f:%l: Validation%t%*[a-z][%*[a-zA-Z]], %m at line:%r'
|
||||
root-markers:
|
||||
- redpen-conf.xml
|
||||
- redpen-conf-??.xml
|
||||
|
||||
redpen-lint: &redpen-lint
|
||||
<<: *redpen-lint-core
|
||||
|
||||
redpen-text-lint: &redpen-text-lint
|
||||
<<: *redpen-lint-core
|
||||
lint-command: 'redpen -l 9999 -f plain -r plain ${INPUT}'
|
||||
|
||||
vint-lint: &vint-lint
|
||||
prefix: vint
|
||||
lint-command: 'vint --enable-neovim --style-problem ${INPUT}'
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m'
|
||||
|
||||
nvcheck-lint: &nvcheck-lint
|
||||
prefix: nvcheck
|
||||
lint-command: 'nvcheck ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-formats:
|
||||
- '%f:%l: %m'
|
||||
root-markers:
|
||||
- dict.yml
|
||||
commands:
|
||||
- title: 'nvcheck fix'
|
||||
command: nvcheck
|
||||
arguments:
|
||||
- '-i'
|
||||
- '${INPUT}'
|
||||
|
||||
markdownlint-lint: &markdownlint-lint
|
||||
prefix: markdownlint
|
||||
lint-command: 'markdownlint --stdin' # markdownlint do not support --stdin-filename like option
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c MD%n/%*[^ ] %m'
|
||||
- '%f:%l MD%n/%*[^ ] %m'
|
||||
commands:
|
||||
- title: 'markdownlint fix'
|
||||
command: markdownlint
|
||||
arguments:
|
||||
- '--fix'
|
||||
- '${INPUT}'
|
||||
|
||||
mdformat-action-format: &mdformat-action-format
|
||||
commands:
|
||||
- title: 'mdformat format'
|
||||
command: mdformat
|
||||
arguments:
|
||||
- '--number'
|
||||
- '--wrap'
|
||||
- 'keep'
|
||||
- '--end-of-line'
|
||||
- 'keep'
|
||||
- '${INPUT}'
|
||||
|
||||
|
||||
pandoc-markdown-format: &pandoc-markdown-format
|
||||
format-command: 'pandoc -f markdown -t gfm -sp --tab-stop=2'
|
||||
format-stdin: true
|
||||
|
||||
pandoc-rst-format: &pandoc-rst-format
|
||||
format-command: 'pandoc -f rst -t rst -s --columns=79'
|
||||
format-stdin: true
|
||||
|
||||
jsonlint-lint: &jsonlint-lint
|
||||
prefix: jsonlint
|
||||
lint-command: 'jsonlint -c'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- 'line %l, col %c, found: %m'
|
||||
|
||||
# not work
|
||||
# jq-lint: &jq-lint
|
||||
# lint-command: 'jq'
|
||||
# lint-stdin: true
|
||||
# lint-offset: 1
|
||||
# lint-formats:
|
||||
# - '%m at line %l, column %c'
|
||||
|
||||
jq-format: &jq-format
|
||||
format-command: 'jq .'
|
||||
format-stdin: true
|
||||
|
||||
fixjson-format: &fixjson-format
|
||||
format-command: 'fixjson'
|
||||
format-stdin: true
|
||||
|
||||
shellcheck-lint: &shellcheck-lint
|
||||
prefix: shellcheck
|
||||
lint-command: 'shellcheck -f gcc -x -'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %t%*[^:]: %m [SC%n]'
|
||||
|
||||
shfmt-format: &shfmt-format
|
||||
format-command: 'shfmt -ln bash -i 2 -bn -ci -sr -kp'
|
||||
format-stdin: true
|
||||
|
||||
checkmake-lint: &checkmake-lint
|
||||
lint-command: 'checkmake'
|
||||
lint-stdin: true
|
||||
|
||||
flake8-lint: &flake8-lint
|
||||
prefix: flake8
|
||||
lint-command: 'flake8 --stdin-display-name ${INPUT} -'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m'
|
||||
root-markers:
|
||||
- setup.cfg
|
||||
- tox.ini
|
||||
- .flake8
|
||||
|
||||
pylint-lint: &pylint-lint
|
||||
prefix: pylint
|
||||
lint-command: 'pylint --output-format=text --score=no --msg-template {path}:{line}:{column}:{C}:{msg} ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-formats:
|
||||
- '%f:%l:%c:%t:%m'
|
||||
lint-offset-columns: 1
|
||||
lint-category-map:
|
||||
I: H
|
||||
R: I
|
||||
C: I
|
||||
W: W
|
||||
E: E
|
||||
F: E
|
||||
root-markers:
|
||||
- setup.cfg
|
||||
- .pylintrc
|
||||
|
||||
mypy-lint: &mypy-lint
|
||||
prefix: mypy
|
||||
lint-command: 'mypy --show-column-numbers --strict --strict-equality'
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %t%*[^:]: %m'
|
||||
root-markers:
|
||||
- setup.cfg
|
||||
- mypy.ini
|
||||
|
||||
black-action-format: &black-action-format
|
||||
commands:
|
||||
- title: 'black format'
|
||||
command: black
|
||||
arguments:
|
||||
- '--quiet'
|
||||
- '--safe'
|
||||
- '${INPUT}'
|
||||
|
||||
yapf-action-format: &yapf-action-format
|
||||
commands:
|
||||
- title: 'yapf format'
|
||||
command: yapf
|
||||
arguments:
|
||||
- '-i'
|
||||
- '${INPUT}'
|
||||
|
||||
isort-action-format: &isort-action-format
|
||||
format-command: 'isort --quiet --profile open_stack -'
|
||||
format-stdin: true
|
||||
|
||||
pydocstyle-lint: &pydocstyle-lint
|
||||
prefix: pydocstyle
|
||||
lint-command: 'pydocstyle ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-ignore-exit-code: true
|
||||
lint-formats:
|
||||
- '%I%f:%l %.%#:'
|
||||
- '%Z%*\sD%n: %m'
|
||||
|
||||
rubocop-lint: &rubocop-lint
|
||||
prefix: rubocop
|
||||
lint-command: 'bundle exec rubocop --format emacs --force-exclusion --stdin ${INPUT}'
|
||||
lint-ignore-exit-code: true
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m'
|
||||
root-markers:
|
||||
- Gemfile
|
||||
- Rakefile
|
||||
- .rubocop.yml
|
||||
commands:
|
||||
- title: 'rubocop fix(safe)'
|
||||
command: bundle
|
||||
arguments:
|
||||
- 'exec'
|
||||
- 'rubocop'
|
||||
- '--autocorrect'
|
||||
- '${INPUT}'
|
||||
- title: 'rubocop fix(all)'
|
||||
command: bundle
|
||||
arguments:
|
||||
- 'exec'
|
||||
- 'rubocop'
|
||||
- '--autocorrect-all'
|
||||
- '${INPUT}'
|
||||
|
||||
rubocop-format: &rubocop-format
|
||||
format-command: 'bundle exec rubocop -A -f quiet --stderr -s ${INPUT}'
|
||||
format-stdin: true
|
||||
|
||||
rufo-format: &rufo-format
|
||||
format-command: 'bundle exec rufo ${INPUT}'
|
||||
format-stdin: false
|
||||
root-markers:
|
||||
- Gemfile
|
||||
- Rakefile
|
||||
- .rufo
|
||||
|
||||
rbprettier-action-format: &rbprettier-action-format
|
||||
commands:
|
||||
- title: 'rbprettier format'
|
||||
command: bundle
|
||||
arguments:
|
||||
- 'exec'
|
||||
- 'rbprettier'
|
||||
- '--write'
|
||||
- '${INPUT}'
|
||||
|
||||
yamllint-lint: &yamllint-lint
|
||||
prefix: yamllint
|
||||
lint-command: 'yamllint --strict --format parsable ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-formats:
|
||||
- '%f:%l:%c: [%t%*[a-z]] %m'
|
||||
env:
|
||||
- 'PYTHONIOENCODING=UTF-8'
|
||||
|
||||
actionlint-lint: &actionlint-lint
|
||||
prefix: actionlint
|
||||
lint-command: "bash -c \"[[ '${INPUT}' =~ \\\\.github/workflows/ ]]\" && actionlint -oneline -no-color -"
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m'
|
||||
root-markers:
|
||||
- .github
|
||||
|
||||
restructuredtext-lint-lint: &restructuredtext-lint-lint
|
||||
prefix: rstlint
|
||||
lint-command: 'rst-lint --encoding utf-8 --level warning --format text ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-ignore-exit-code: true
|
||||
lint-formats:
|
||||
- '%t%*[A-Z] %f:%l %m'
|
||||
|
||||
rstcheck-lint: &rstcheck-lint
|
||||
prefix: rstcheck
|
||||
lint-command: 'rstcheck --report warning -'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l: (%t%*[^/]/%n) %m'
|
||||
|
||||
textlint-lint: &textlint-lint
|
||||
prefix: textlint
|
||||
lint-command: 'npx --no-install textlint -f unix --no-color --stdin --stdin-filename ${INPUT}'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m [%trror/%r]'
|
||||
- '%f:%l:%c: 【%r】 %m'
|
||||
- '%E%f:%l:%c: %m'
|
||||
- '%Z%m [%trror/%r]'
|
||||
- '%C%m'
|
||||
root-markers:
|
||||
- package.json
|
||||
- .textlintrc
|
||||
commands:
|
||||
- title: 'textlint fix'
|
||||
command: npx
|
||||
arguments:
|
||||
- '--no-install'
|
||||
- 'textlint'
|
||||
- '--fix'
|
||||
- '${INPUT}'
|
||||
|
||||
eslint-lint: &eslint-lint
|
||||
prefix: eslint
|
||||
lint-command: 'npx --no-install eslint -f unix --stdin --stdin-filename ${INPUT}'
|
||||
lint-ignore-exit-code: true
|
||||
lint-stdin: true
|
||||
root-markers:
|
||||
- package.json
|
||||
- .eslintrc.js
|
||||
- .eslintrc.yaml
|
||||
- .eslintrc.yml
|
||||
- .eslintrc.json
|
||||
commands:
|
||||
- title: 'eslint fix'
|
||||
command: npx
|
||||
arguments:
|
||||
- '--no-install'
|
||||
- 'eslint'
|
||||
- '--fix'
|
||||
- '${INPUT}'
|
||||
|
||||
stylelint-lint: &stylelint-lint
|
||||
prefix: stylelint
|
||||
lint-command: 'npx --no-install stylelint --formatter unix --stdin --stdin-filename ${INPUT}'
|
||||
lint-ignore-exit-code: false
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %m [%t%*[a-z]]'
|
||||
root-markers:
|
||||
- package.json
|
||||
- .stylelintrc.json
|
||||
commands:
|
||||
- title: 'stylelint fix'
|
||||
command: npx
|
||||
arguments:
|
||||
- '--no-install'
|
||||
- 'stylelint'
|
||||
- '--fix'
|
||||
- '${INPUT}'
|
||||
|
||||
htmllint-lint: &htmllint-lint
|
||||
prefix: htmllint
|
||||
lint-command: 'npx --no-install htmllint ${INPUT}'
|
||||
lint-stdin: false
|
||||
lint-formats:
|
||||
- '%f: line %l, col %c, %m'
|
||||
root-markers:
|
||||
- package.json
|
||||
- .htmllintrc
|
||||
|
||||
buf-lint: &buf-lint
|
||||
prefix: buf
|
||||
lint-command: 'buf lint --path'
|
||||
root-markers:
|
||||
- buf.yaml
|
||||
|
||||
prettier-action-fix: &prettier-action-fix
|
||||
commands:
|
||||
- title: 'prettier fix'
|
||||
command: npx
|
||||
arguments:
|
||||
- '--no-install'
|
||||
- 'prettier'
|
||||
- '--fix'
|
||||
- '--write'
|
||||
- '${INPUT}'
|
||||
|
||||
credo-lint: &credo-lint
|
||||
prefix: credo
|
||||
lint-command: 'mix credo suggest --format=flycheck --read-from-stdin ${INPUT}'
|
||||
lint-stdin: true
|
||||
lint-formats:
|
||||
- '%f:%l:%c: %t: %m'
|
||||
- '%f:%l: %t: %m'
|
||||
root-markers:
|
||||
- mix.lock
|
||||
- mix.exs
|
||||
|
||||
hadolint-lint: &hadolint-lint
|
||||
prefix: hadolint
|
||||
lint-command: 'hadolint'
|
||||
lint-formats:
|
||||
- '%f:%l %m'
|
||||
|
||||
cspell-lint: &cspell-lint
|
||||
prefix: cspell
|
||||
lint-command: 'npx --no-install cspell lint --no-progress --no-summary --no-color ${INPUT}'
|
||||
lint-formats:
|
||||
- '%f:%l:%c - %m'
|
||||
- '%f:%l:%c %m'
|
||||
root-markers:
|
||||
- package.json
|
||||
- .cspell.json
|
||||
- cspell.json
|
||||
- .cSpell.json
|
||||
- cSpell.json
|
||||
- cspell.config.js
|
||||
- cspell.config.cjs
|
||||
- cspell.config.json
|
||||
- cspell.config.yaml
|
||||
- cspell.config.yml
|
||||
- cspell.yaml
|
||||
- cspell.yml
|
||||
|
||||
excitetranslate-hover: &excitetranslate-hover
|
||||
hover-command: 'excitetranslate'
|
||||
hover-stdin: true
|
||||
|
||||
# languages setting
|
||||
languages:
|
||||
vim:
|
||||
- <<: *vint-lint
|
||||
|
||||
markdown:
|
||||
- <<: *markdownlint-lint
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-lint
|
||||
- <<: *vale-lint
|
||||
- <<: *nvcheck-lint
|
||||
- <<: *stylelint-lint
|
||||
- <<: *prettier-action-fix
|
||||
- <<: *pandoc-markdown-format
|
||||
- <<: *mdformat-action-format
|
||||
|
||||
json:
|
||||
- <<: *jsonlint-lint
|
||||
- <<: *jq-format
|
||||
- <<: *fixjson-format
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
json5:
|
||||
- <<: *fixjson-format
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
text:
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-text-lint
|
||||
- <<: *vale-lint
|
||||
- <<: *nvcheck-lint
|
||||
|
||||
help:
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-text-lint
|
||||
- <<: *vale-lint
|
||||
- <<: *nvcheck-lint
|
||||
|
||||
cpp:
|
||||
- <<: *cppcheck-lint
|
||||
|
||||
c:
|
||||
- <<: *cppcheck-lint
|
||||
|
||||
sh:
|
||||
- <<: *shellcheck-lint
|
||||
- <<: *shfmt-format
|
||||
|
||||
make:
|
||||
- <<: *checkmake-lint
|
||||
|
||||
yaml:
|
||||
- <<: *yamllint-lint
|
||||
- <<: *prettier-action-fix
|
||||
- <<: *actionlint-lint
|
||||
|
||||
rst:
|
||||
- <<: *restructuredtext-lint-lint
|
||||
- <<: *rstcheck-lint
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-lint
|
||||
- <<: *vale-lint
|
||||
- <<: *nvcheck-lint
|
||||
- <<: *pandoc-rst-format
|
||||
|
||||
asciidoc:
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-lint
|
||||
|
||||
review:
|
||||
- <<: *textlint-lint
|
||||
- <<: *redpen-lint
|
||||
|
||||
javascript:
|
||||
- <<: *eslint-lint
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
typescript:
|
||||
- <<: *eslint-lint
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
css:
|
||||
- <<: *stylelint-lint
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
scss:
|
||||
- <<: *stylelint-lint
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
sass:
|
||||
- <<: *stylelint-lint
|
||||
|
||||
less:
|
||||
- <<: *stylelint-lint
|
||||
|
||||
sugarss:
|
||||
- <<: *stylelint-lint
|
||||
|
||||
proto:
|
||||
- <<: *buf-lint
|
||||
|
||||
python:
|
||||
- <<: *flake8-lint
|
||||
- <<: *pydocstyle-lint
|
||||
- <<: *isort-action-format
|
||||
# - <<: *pylint-lint
|
||||
# - <<: *mypy-lint
|
||||
# - <<: *black-action-format
|
||||
# - <<: *yapf-action-format
|
||||
|
||||
ruby:
|
||||
- <<: *rubocop-lint
|
||||
- <<: *rubocop-format
|
||||
- <<: *rufo-format
|
||||
- <<: *rbprettier-action-format
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
graphql:
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
vue:
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
html:
|
||||
- <<: *textlint-lint
|
||||
- <<: *htmllint-lint
|
||||
- <<: *stylelint-lint
|
||||
- <<: *prettier-action-fix
|
||||
|
||||
elixir:
|
||||
- <<: *credo-lint
|
||||
|
||||
dockerfile:
|
||||
- <<: *hadolint-lint
|
||||
|
||||
=:
|
||||
- <<: *excitetranslate-hover
|
||||
- <<: *cspell-lint
|
||||
...
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<alias>
|
||||
<family>Fira Code</family>
|
||||
<prefer>
|
||||
<family>Font Awesome 5 Brands</family>
|
||||
<family>Font Awesome 5 Free</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>Fira Mono</family>
|
||||
<prefer>
|
||||
<family>Font Awesome 5 Brands</family>
|
||||
<family>Font Awesome 5 Free</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<prefer>
|
||||
<family>Font Awesome 5 Brands</family>
|
||||
<family>Font Awesome 5 Free</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>DejaVu Sans Mono for Powerline</family>
|
||||
<prefer>
|
||||
<family>Font Awesome 5 Brands</family>
|
||||
<family>Font Awesome 5 Free</family>
|
||||
</prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Don't let ripgrep vomit really long lines to my terminal, and show a preview.
|
||||
--max-columns=250
|
||||
--max-columns-preview
|
||||
|
||||
# Using glob patterns to include/exclude files or folders
|
||||
# --glob=!git/*
|
||||
# Exclude directories.
|
||||
--glob=!{.git,.svn,node_modules,tealdeer,Trash,vendor,site-packages}
|
||||
|
||||
# Exclude file types.
|
||||
--glob=!*.{lock}
|
||||
--glob=!dist/*
|
||||
--glob=!build*
|
||||
--glob=!.cache/*
|
||||
# Exclude files.
|
||||
--glob=!{package-lock.json}
|
||||
--glob=!log/*
|
||||
# # or
|
||||
# --glob
|
||||
# '!{**/node_modules/*,**/.git/*}'
|
||||
# --glob
|
||||
# '!{.git,**/vendor/*,**/node_modules/*}'
|
||||
# Set the colors.
|
||||
--colors=line:none
|
||||
--colors=line:style:bold
|
||||
|
||||
# Because who cares about case!?
|
||||
--smart-case
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
# vim: ft=yaml
|
||||
|
||||
yaml-files:
|
||||
- '*.yaml'
|
||||
- '*.yml'
|
||||
- '.yamllint'
|
||||
|
||||
rules:
|
||||
anchors: enable
|
||||
braces: enable
|
||||
brackets: enable
|
||||
colons: enable
|
||||
commas: enable
|
||||
comments:
|
||||
level: warning
|
||||
comments-indentation:
|
||||
level: warning
|
||||
document-end: disable
|
||||
document-start:
|
||||
level: warning
|
||||
empty-lines: enable
|
||||
empty-values: disable
|
||||
float-values: disable
|
||||
hyphens: enable
|
||||
indentation: enable
|
||||
key-duplicates: enable
|
||||
key-ordering: disable
|
||||
line-length: disable
|
||||
new-line-at-end-of-file: enable
|
||||
new-lines: enable
|
||||
octal-values: disable
|
||||
quoted-strings: disable
|
||||
trailing-spaces: enable
|
||||
truthy:
|
||||
level: warning
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# ctags
|
||||
|
||||
builded from https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
--langdef=puppet
|
||||
--langmap=puppet:.pp
|
||||
--regex-puppet=/^[[:space:]]*class[[:space:]]*([a-z][a-zA-Z0-9_:\-]+)/\1/c,class/
|
||||
--regex-puppet=/^[[:space:]]*site[[:space:]]*([a-zA-Z0-9_\-]+)/\1/s,site/
|
||||
--regex-puppet=/^[[:space:]]*node[[:space:]]*[\'|\"]*([a-zA-Z0-9_\.\-]+)[\'|\"]*/\1/n,node/
|
||||
--regex-puppet=/^[[:space:]]*define[[:space:]]*([a-z][a-zA-Z0-9_:\-]+)/\1/d,definition/
|
||||
--regex-puppet=/^[[:space:]]*(include|require)[[:space:]]*([a-zA-Z0-9_:]+)/\1 \2/i,include/
|
||||
--regex-puppet=/^[[:space:]]*([\$][a-zA-Z0-9_:]+)[[:space:]]*=/\1/v,variable/
|
||||
--regex-puppet=/^[[:space:]]*[~|\-]?>?[[:space:]]*([a-z][a-zA-Z0-9_:]+)[[:space:]]*\{ *(.*):/\1[\2]/r,resource/
|
||||
--regex-puppet=/([A-Z][a-zA-Z0-9_:]+)[[:space:]]*\{/\1/f,default/
|
||||
--regex-puppet=/^[[:space:]]*type[[:space:]]*([A-Z][a-zA-Z0-9_:]*)[[:space:]]*=/\1/t,type/
|
||||
--regex-puppet=/^[[:space:]]*function[[:space:]]*([a-zA-Z0-9_:]*)[[:space:]]*/\1/u,function/
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue