freelance-project-34-market.../dotfiles/.local/bin/commands
2022-11-07 15:30:40 +03:00

968 lines
28 KiB
Python
Executable File

#!/usr/bin/env python3
import re
import datetime
import sys
import select
import subprocess
import pprint
import socket
import optparse
import os
import json
import traceback
import time
import sys
import io
import subprocess
import logging
msg = None
def intercept_output(
current_subprocess,
return_aggregated=None,
transform_callback=None,
):
if not return_aggregated:
return_aggregated = False
t1 = select.poll()
t1.register(current_subprocess.stdout, select.POLLIN)
print([current_subprocess, current_subprocess.poll()])
output = []
last_data = None
while not (
not current_subprocess.poll() is None and \
not last_data is None and len(last_data) == 0
):
t2 = t1.poll(100)
if len(t2) == 1 and (t2[0][1] & select.POLLIN) > 0 and \
not (isinstance(last_data, bytes) and len(last_data) == 0):
t3 = current_subprocess.stdout.peek()
t4 = current_subprocess.stdout.read(len(t3))
last_data = t3
output.append(t3)
yield dict(
data=t3,
aggregated=False,
)
t6 = t3
if not transform_callback is None:
t5 = transform_callback(t3)
if not t5 is None:
t6 = t5
os.write(sys.stdout.fileno(), t6)
if return_aggregated:
yield dict(
data=b''.join(output),
aggregated=True,
returncode=current_subprocess.poll(),
)
def player_metadata():
for k in range(20):
try:
time.sleep(1.0)
return subprocess.check_output(['playerctl', 'metadata']).decode('utf-8').strip()
except:
continue
def memory_stats():
with io.BytesIO(subprocess.check_output('free', shell=True)) as f:
t1 = f.read().decode('utf-8').splitlines()
mem_total = int(t1[1].strip().split()[1])
mem_used = int(t1[1].strip().split()[2])
return dict(
mem_total=mem_total,
mem_used=mem_used,
)
def eternal_oom(memory_limit=None):
import signal
import re
import time
import pprint
self_pid = os.getpid()
if memory_limit is None:
memory_limit = 3 * 1024 * 1024
assert isinstance(memory_limit, int) \
and memory_limit < memory_stats()['mem_total'] * 0.8 \
and memory_limit > 512 * 1024
def pandas_data_frame(lines, groups_regex, header_regex, extra_columns):
header = re.compile(header_regex).search(lines[0]).groups()
rows = [
re.compile(groups_regex).search(row).groups()
for row in lines[1:]
]
columns = {
column: []
for column in header
}
for row in rows:
for value, column in zip(row, header):
columns[column].append(value)
for column, transformation in extra_columns.items():
columns[column] = [
transformation(
{
k : v[index]
for k, v in columns.items()
}
)
for index in range(len(rows))
]
return columns
def pandas_merge(left, right, on):
index = {}
input_data_frames = [
('left', left),
('right', right),
]
for index_name, data_frame in input_data_frames:
current_index = {}
for row_index, value in enumerate(data_frame[on]):
if not value in current_index:
current_index[value] = []
current_index[value].append(row_index)
index[index_name] = current_index
merged_data_frame = dict(
header=[
column + '_x'
for column in left
] + [
column + '_y'
for column in right
],
columns={},
)
for column in merged_data_frame['header']:
merged_data_frame['columns'][column] = []
common_values = {
left_value
for left_value in index['left']
if left_value in index['right']
}
common_rows = sorted(
[
dict(
left_row_index=index['left'][value][0],
right_row_index=index['right'][value][0],
)
for value in common_values
],
key=lambda x: x['left_row_index'],
)
for common_row in common_rows:
row = sum([
[
values[
common_row['%s_row_index' % index_name]
]
for column, values in data_frame.items()
]
for index_name, data_frame in input_data_frames
], [])
for column, value in zip(merged_data_frame['header'], row):
merged_data_frame['columns'][column].append(value)
return merged_data_frame['columns']
def pandas_sort_values(data_frame, by, ascending):
assert len(by) == 1
assert ascending is False
t1 = [
o['row_index']
for o in sorted(
[
dict(
row_index=row_index,
value=value
)
for row_index, value in enumerate(data_frame[by[0]])
],
key=lambda x: x['value']
)[::-1]
]
return {
column : [
values[row_index]
for row_index in t1
]
for column, values in data_frame.items()
}
def pandas_filter_values(data_frame, condition):
shape = [
len(data_frame),
]
if shape[0] > 0:
shape.append(
len(list(data_frame.values())[0])
)
t1 = [
row_index
for row_index in range(shape[1])
if condition(
{
column : values[row_index]
for column, values in data_frame.items()
}
)
]
return {
column : [
values[row_index]
for row_index in t1
]
for column, values in data_frame.items()
}
def pandas_row(data_frame, row_index):
return {
column : values[row_index]
for column, values in data_frame.items()
}
while True:
with io.BytesIO(subprocess.check_output('ps -e -o pid,rss,user', shell=True)) as f:
t1 = pandas_data_frame(
f.read().decode('utf-8').splitlines(),
r'^\s*([^\s]+)\s+([^\s]+)\s+([^\s]+)\s*$',
r'^\s*([^\s]+)\s+([^\s]+)\s+([^\s]+)\s*$',
dict(
PID=lambda row: int(row['PID']),
RSS=lambda row: int(row['RSS']),
),
)
mem_used = memory_stats()['mem_used']
t5 = subprocess.check_output('ps -e -o pid,args', shell=True).decode('utf-8').splitlines()
t6 = pandas_data_frame(
t5,
r'^\s*(\d+)\s(.*)$',
r'^\s+(\w+)\s+(\w+)\s*$',
dict(
PID=lambda row: int(row['PID'])
),
)
t7 = pandas_merge(t1, t6, on='PID')
t8 = pandas_sort_values(t7, by=['RSS_x'], ascending=False)
t9 = pandas_filter_values(
t8,
lambda row: row['PID_x'] != self_pid and not 'freelancer' in row['COMMAND_y']
)
t4 = lambda : os.kill(t9['PID_x'][0], signal.SIGKILL)
t10 = lambda : mem_used > memory_limit
if t10():
pprint.pprint([
'Killing',
pandas_row(t9, 0),
mem_used,
])
t4()
time.sleep(1)
def resilient_vlc(stream=None):
if stream is None:
streams_path = os.path.join(
os.environ['CACHE_PATH'],
'resilient-vlc-streams.json'
)
if os.path.exists(streams_path):
with io.open(
streams_path,
'r'
) as f:
stream = json.load(f)
else:
raise RuntimeError(
'not found, %s' % streams_path
)
if isinstance(stream, str):
stream = [stream]
if len(stream) == 0:
raise RuntimeError('no streams')
import subprocess
import time
while True:
print('new start')
with subprocess.Popen([
'cvlc', '--verbose', '2', *stream,
], stderr=subprocess.PIPE) as p:
while p.returncode is None:
t1 = p.stderr.readline().decode('utf-8')
if len(t1) > 0:
print(t1)
if not all([
o in t1
for o in [
'prefetch stream error',
'terror',
'main interface error',
]
]) and any([
o in t1
for o in [
'pulse audio output debug: underflow'
]
]):
print('shit')
p.kill()
while True:
try:
t2 = p.wait(timeout=1)
print(t2)
break
except:
print('shit')
pass
time.sleep(1.0)
def eternal_firefox(
tabs=None,
profile=None,
group_name=None,
window_position=None,
debug=None,
):
import os
import datetime
import pprint
import subprocess
import time
if debug is None:
debug = False
if tabs is None:
raise RuntimeError('no tabs provided')
if profile is None:
raise RuntimeError('no profile provided')
if group_name is None:
raise RuntimeError('no group provided')
if window_position is None:
#window_position = '1,600,0,600,540'
raise RuntimeError('no window-position provided')
while True:
os.system(r'''date''')
with subprocess.Popen([
'firefox',
'-P', profile,
*tabs,
]) as p:
try:
if debug:
assert subprocess.check_call(['notify-send', '%s:Starting' % group_name]) == 0
#t3 = ''
for k in range(300):
t1 = subprocess.check_output(r'''
swaymsg -t get_tree | jq -r '..|try select(.pid== %d)'
''' % p.pid, shell=True).decode('utf-8')
if len(t1) > 10:
break
#time.sleep(0.1)
#t1 = subprocess.check_output(['wmctrl', '-p', '-l']).decode('utf-8')
#t4 = [o for o in t1.splitlines() if str(p.pid) in o]
#if len(t4) == 1:
# t3 = t4[0]
# break
#if t3 == '':
# raise RuntimeError
#t2 = t3.split()[0]
#assert os.system('wmctrl -i -r %s -e %s' % (t2, window_position)) == 0
#assert os.system('wmctrl -i -r %s -b add,below' % t2) == 0
def reposition():
t1 = lambda s: \
s \
.replace('{{PID}}', str(p.pid)) \
.replace('{{X}}', str(window_position[1])) \
.replace('{{Y}}', str(window_position[2])) \
.replace('{{W}}', str(window_position[3])) \
.replace('{{H}}', str(window_position[4])) \
.replace('{{WORKSPACE}}', str(window_position[0]))
assert os.system(t1(r'''
swaymsg '[pid="{{PID}}"] move window to workspace {{WORKSPACE}}'
''')) == 0
if window_position[1] != '' and window_position[2] != '':
assert os.system(t1(r'''
swaymsg '[pid="{{PID}}"] floating enable' \
swaymsg '[pid="{{PID}}"] resize set width {{W}}px height {{H}}px' && \
swaymsg '[pid="{{PID}}"] move absolute position {{X}}px {{Y}}px'
''')) == 0
else:
assert os.system(t1(r'''
swaymsg '[pid="{{PID}}"] floating disable'
''')) == 0
if False:
for tab in tabs[1:]:
time.sleep(10)
assert subprocess.check_call([
'firefox',
'-P', profile,
'--new-tab',
tab,
]) == 0
reposition()
if debug:
assert subprocess.check_call(['notify-send', '%s:Started' % group_name]) == 0
start = datetime.datetime.now()
is_to_restart = lambda : (datetime.datetime.now() - start).total_seconds() >= 900 * 4
polling_count = 0
while not is_to_restart():
if polling_count == 0:
reposition()
if not p.poll() is None:
break
time.sleep(10)
polling_count += 1
if debug:
assert subprocess.check_call(['notify-send', '%s:Closing' % group_name]) == 0
#assert os.system('wmctrl -i -c %s' % t2) == 0
assert os.system(r'''
swaymsg '[pid="%d"] kill'
''' % (p.pid,)) == 0
except KeyboardInterrupt:
assert os.system(r'''
swaymsg '[pid="%d"] kill'
''' % (p.pid,)) == 0
break
except:
import traceback
import pprint
pprint.pprint(traceback.format_exc())
finally:
try:
p.wait(20)
except subprocess.TimeoutExpired:
pprint.pprint([p.pid, '20 seconds timeout', 'kill'])
p.kill()
if debug:
assert subprocess.check_call(['notify-send', '%s:Closed' % group_name]) == 0
def resilient_ethernet(ip_addr, ethernet_device):
subprocess.check_call(
r'''
sudo sh -c '\
while true; \
do ping -c 3 -w 3 -W 1 {{IP_ADDR}} || (\
ip link set {{ETHERNET_DEVICE}} down; \
ip link set {{ETHERNET_DEVICE}} up; \
sleep 4; true;\
); \
sleep 10; clear; date; \
done'
'''.replace(
'{{IP_ADDR}}',
ip_addr
).replace(
'{{ETHERNET_DEVICE}}}',
ethernet_device
),
shell=True
)
def http_server(argv):
assert isinstance(argv, list) and all([isinstance(o, str) for o in argv])
parser = optparse.OptionParser()
parser.add_option(
'--public',
dest='public',
action='store_true',
default=False,
)
parser.add_option(
'--port',
dest='port',
type='int',
default=80,
)
parser.add_option(
'--host',
dest='host',
type='str',
default='127.0.0.1',
)
options, args = parser.parse_args(argv)
assert options.port >= 1
try:
assert not socket.inet_aton(options.host) is None
subprocess.check_call([
'ping', '-w', '1',
options.host
])
except:
raise RuntimeError('invalid ip address %s' % options.host)
index_section = 'autoindex on;'
if len(sys.argv) == 3 and sys.argv[2] == '--public':
location_section = 'location / {%s}' % index_section
else:
token = os.urandom(16).hex()
print(
'access url is http://%s:%d/%s/' % (
options.host,
options.port,
token,
)
)
location_section = (
'location / {'
'deny all;'
'}'
'location /%s/ {'
'alias /app/;'
'%s'
'}'
) % (token, index_section)
subprocess.check_call(
r'''
sudo docker run \
-p %s:%d:80 \
-u root \
-it --entrypoint=/bin/bash \
-v $PWD:/app:ro \
nginx:latest \
-c 'echo "server{listen 80; charset UTF-8; root /app; %s}" > /etc/nginx/conf.d/default.conf; nginx -g "daemon off;"'
''' % (
options.host,
options.port,
location_section,
),
shell=True)
def pass_ssh_osx(argv):
assert isinstance(argv, list) and all([isinstance(o, str) for o in argv])
parser = optparse.OptionParser()
parser.add_option(
'--list',
dest='list',
default=False,
action='store_true',
)
parser.add_option(
'--pass_option',
dest='pass_option',
action='append',
default=[],
type=str,
)
parser.add_option(
'--debug',
dest='debug',
action='store_true',
default=False,
)
assert sys.platform == 'darwin'
options, args = parser.parse_args(argv)
if len(args) == 0:
raise RuntimeError('ssh_command is required')
if options.debug:
print(options.pass_option)
pprint.pprint(args)
t1 = options.pass_option
assert len(t1) > 0
reset_gpg_agent = r'''
gpgconf --kill gpg-agent && \
gpgconf --reload gpg-agent
'''
if not options.list:
print(
'select on of pass names\n%s' % '\n'.join([
'%d: %s' % (k, v)
for k, v in enumerate(t1)
])
)
while True:
try:
t2 = input()
t3 = int(t2)
assert t3 >= 0 and t3 < len(t1)
break
except:
continue
command = r'''
%s
gpg \
--pinentry-mode=ask \
-q -u $(cat ~/.password-store/.gpg-id) \
--decrypt \
~/.password-store/%s.gpg && \
echo -n '['$?']' && \
%s
''' % (
reset_gpg_agent,
t1[t3],
reset_gpg_agent,
)
else:
command = 'pass list | less -R'
ssh_command = [
'ssh', '-C',
'-o', 'ConnectTimeout 10',
'-o', 'ServerAliveInterval 1',
*args,
'-t',
command,
]
if options.debug:
pprint.pprint(
dict(
ssh_command=ssh_command,
)
)
if options.list:
subprocess.check_call(ssh_command)
else:
def cliboard_set(text):
with subprocess.Popen([
'pbcopy',
], stdin=subprocess.PIPE) as p:
p.stdin.write(text.encode('utf-8'))
p.stdin.flush()
p.stdin.close()
p.wait(1)
assert p.poll() == 0
with subprocess.Popen(
ssh_command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) as p:
password = None
last_chunk = None
hide_password = False
pinentry_delimeter = b'\x1b>'
def transform_callback(data):
nonlocal hide_password
nonlocal pinentry_delimeter
data2 = None
if pinentry_delimeter in data:
hide_password = True
pos = data.rfind(pinentry_delimeter)
if pos == -1:
data2 = data
else:
data2 = data[:pos + len(pinentry_delimeter)]
elif data == b'':
#return b'\r\n'
return b''
elif hide_password:
data2 = b''
else:
data2 = None
return data2
for chunk in intercept_output(
current_subprocess=p,
return_aggregated=True,
transform_callback=transform_callback,
):
if chunk['aggregated']:
last_chunk = chunk
break
assert not last_chunk is None
assert last_chunk['returncode'] == 0
if options.debug:
pprint.pprint(last_chunk['data'])
if last_chunk['data'].endswith('\r\n[0]'.encode('utf-8')) and \
last_chunk['data'].rfind(pinentry_delimeter) != -1:
last_line = last_chunk['data'].splitlines()[-2]
else:
raise RuntimeError(
'gpg failure %s' % str(
last_chunk['data'][
max(last_chunk['data'].find(pinentry_delimeter), -128):
]
)
)
pos2 = last_line.rfind(pinentry_delimeter)
if pos2 == -1:
last_line2 = last_line
else:
last_line2 = last_line[
pos2 + len(pinentry_delimeter):
]
password = last_line2.decode('utf-8').rstrip('\r\n')
assert not password is None
cliboard_set(password)
get_time = lambda : datetime.datetime.now().timestamp()
start = get_time()
while True:
cur = get_time()
remains = 10 - (cur - start)
if remains <= 1e-8:
break
else:
print('\r%5.2fs remains' % remains, end='')
time.sleep(0.1)
cliboard_set('')
print('\rcleared cliboard\n', end='')
def player_v1(folder_url, item_id):
import sys
import urllib.parse
import re
import subprocess
import os
import tqdm
t4 = folder_url
t1 = subprocess.check_output(['curl', '-s', t4]).decode('utf-8')
t2 = re.compile(r"href=\"(.*\.mp3)\"");
t3 = [o.group(1) for o in t2.finditer(t1)];
t5 = ['%s/%s' % (t4, o) for o in t3]
t6 = item_id
t9 = range(t6, len(t5))
with tqdm.tqdm(
total=len(t5),
) as progress_bar:
progress_bar.update(t6)
for k in t9:
t7 = t5[k]
t9 = urllib.parse.unquote(os.path.split(t7)[1])
progress_bar.set_description('%03d %s' % (k, t9))
with subprocess.Popen(['ffprobe', '-hide_banner', '-i', t7], stderr=subprocess.PIPE, stdout=subprocess.PIPE) as p:
p.wait()
assert p.returncode == 0
t8 = p.stderr.read().decode('utf-8')
#print(t8)
with subprocess.Popen(['ffplay', '-hide_banner', '-nodisp', '-autoexit', '-loop', '1', t7], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) as p:
p.wait()
assert p.returncode == 0
progress_bar.update(1)
def status():
return ' | '.join([
subprocess.check_output(o, shell=True).decode('utf-8').strip()
for o in [
r'''
free -h | \
grep -P Mem: | grep -Po '[\w\.\d]+' | tail -n +2 | head -n 3 | xargs echo -n;
''',
r'''
sensors | \
grep -Po '[\\\+\\\-\\\w][^\\\s]+C ' | head -n 5 | xargs echo -n
''',
r'''
ssh nartes@pizcool3070 free -h | \
grep -P Mem: | grep -Po '[\w\.\d]+' | tail -n +2 | head -n 3 | xargs echo -n;
''',
r'''
ssh nartes@pizcool3070 sensors | \
grep -Po '[\\\+\\\-\.0-9]+\s+C ' | head -n 1
''',
r'''
date +'%Y-%m-%d %l:%M:%S %p';
''',
]
]).replace('\n\r', '')
def custom_translate(current_string, check, none_char=None,):
if none_char is None:
none_char = '.'
class A:
def __getitem__(self, k):
t1 = chr(k)
t2 = check(k, t1)
if isinstance(t2, bool):
if t2:
return t1
else:
return none_char
elif isinstance(t2, str):
return t2
return current_string.translate(
A()
)
try:
if sys.argv[1] == 'media-play-pause':
subprocess.check_call(['playerctl', 'play-pause'])
msg = player_metadata()
elif sys.argv[1] == 'media-next':
subprocess.check_call(['playerctl', 'next'])
msg = player_metadata()
elif sys.argv[1] == 'media-prev':
subprocess.check_call(['playerctl', 'previous'])
msg = player_metadata()
elif sys.argv[1] == 'media-lower-volume':
subprocess.check_call([
'pactl',
'set-sink-volume',
'@DEFAULT_SINK@',
'-5%'
])
msg = subprocess.check_output([
'pactl',
'get-sink-volume',
'@DEFAULT_SINK@'
]).decode('utf-8').strip()
elif sys.argv[1] == 'media-raise-volume':
subprocess.check_call([
'pactl',
'set-sink-volume',
'@DEFAULT_SINK@',
'+5%'
])
msg = subprocess.check_output([
'pactl',
'get-sink-volume',
'@DEFAULT_SINK@'
]).decode('utf-8').strip()
elif sys.argv[1] == 'status':
sys.stdout.write(status())
sys.stdout.flush()
elif sys.argv[1] == 'http-server':
http_server(sys.argv[2:])
elif sys.argv[1] == 'pass-ssh-osx':
pass_ssh_osx(sys.argv[2:])
elif sys.argv[1] == 'wl-screenshot':
subprocess.check_call(r'''
grim -g "$(slurp)" - | wl-copy
''', shell=True)
elif sys.argv[1] == 'eternal-oom':
eternal_oom(
memory_limit=json.loads(sys.argv[2]),
)
elif sys.argv[1] == 'resilient-vlc':
resilient_vlc(sys.argv[2:])
elif sys.argv[1] == 'eternal-firefox':
eternal_firefox(
profile=sys.argv[2],
group_name=sys.argv[3],
window_position=json.loads(sys.argv[4]),
debug=json.loads(sys.argv[5]),
tabs=sys.argv[6:],
)
elif sys.argv[1] == 'resilient-ethernet':
resilient_ethernet(
ip_addr=sys.argv[2],
ethernet_device=sys.argv[3],
)
elif sys.argv[1] == 'player':
player_v1(
folder_url=sys.argv[2],
item_id=int(sys.argv[3]),
)
elif sys.argv[1] == 'desktop-services':
assert all([
env_name in os.environ
for env_name in [
'GTK_IM_MODULE',
'XMODIFIERS',
'QT_IM_MODULE',
'I3SOCK',
'SWAYSOCK',
'WAYLAND_DISPLAY',
]
])
services = []
try:
services.extend([
subprocess.Popen(['ibus-daemon']),
subprocess.Popen(r'''
swayidle -w \
timeout 300 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"'
''', shell=True),
])
for o in services:
o.wait()
finally:
for o in services:
try:
o.terminate(timeout=10)
except:
logging.error('killed %s' % str(o.__dict__))
o.kill()
else:
raise NotImplementedError
except SystemExit:
pass
except:
msg = 'not implemented\n%s' % traceback.format_exc()
logging.error(msg)
if not msg is None:
if sys.platform == 'darwin':
subprocess.check_call([
'osascript',
'-e',
'display notification "%s" with title "commands failure"' % (
custom_translate(
msg,
lambda a, b:
not re.compile(
r'^[a-zA-Z0-9\<\>\/\(\)\s\.\,\:]*$'
)\
.match(b) is None,
)
)
])
else:
subprocess.check_call([
'notify-send',
'commands',
msg[-128:]
])