From 58e35d78dddc3a11824ec990220beece1109330b Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 17 Jun 2021 17:17:05 +0100 Subject: [PATCH] Added lots of stuff needing to be backed up. --- gpu_usage/README | 1 + gpu_usage/etc_local.d_gpu_usage.start | 2 + gpu_usage/etc_local.d_gpu_usage.stop | 3 + gpu_usage/gpu_usage | 66 +++ minecraft/etc_init.d_spigot | 46 ++ minecraft/usr_sbin_spigot_service | 200 ++++++++ pi_temp_daemon/README.md | 3 + pi_temp_daemon/etc_init.d_pitempd | 39 ++ pi_temp_daemon/usr_sbin_pitempd | 434 ++++++++++++++++++ python_3.9_compat/python3_9-py-checker | 119 +++++ python_3.9_compat/python3_9-py-logger | 120 +++++ python_3.9_compat/python_3_9_compat.sh | 136 ++++++ random_scripts/TV-On | 6 + random_scripts/etc_local.d_nfs_mounts.stopper | 26 ++ random_scripts/etc_local.d_soundcard.start | 15 + .../etc_local.d_tcp_syn_retries.stop | 4 + random_scripts/shebang_test.py | 6 + random_scripts/speech.sh | 6 + random_scripts/ytplay | 16 + 19 files changed, 1248 insertions(+) create mode 100644 gpu_usage/README create mode 100755 gpu_usage/etc_local.d_gpu_usage.start create mode 100755 gpu_usage/etc_local.d_gpu_usage.stop create mode 100755 gpu_usage/gpu_usage create mode 100755 minecraft/etc_init.d_spigot create mode 100755 minecraft/usr_sbin_spigot_service create mode 100644 pi_temp_daemon/README.md create mode 100755 pi_temp_daemon/etc_init.d_pitempd create mode 100755 pi_temp_daemon/usr_sbin_pitempd create mode 100755 python_3.9_compat/python3_9-py-checker create mode 100755 python_3.9_compat/python3_9-py-logger create mode 100755 python_3.9_compat/python_3_9_compat.sh create mode 100755 random_scripts/TV-On create mode 100755 random_scripts/etc_local.d_nfs_mounts.stopper create mode 100755 random_scripts/etc_local.d_soundcard.start create mode 100755 random_scripts/etc_local.d_tcp_syn_retries.stop create mode 100755 random_scripts/shebang_test.py create mode 100755 random_scripts/speech.sh create mode 100755 random_scripts/ytplay diff --git a/gpu_usage/README b/gpu_usage/README new file mode 100644 index 0000000..3bee6a4 --- /dev/null +++ b/gpu_usage/README @@ -0,0 +1 @@ +Was too lazy to write an initscript, so made /etc/local.d/ x.start and x.stop scripts instead. diff --git a/gpu_usage/etc_local.d_gpu_usage.start b/gpu_usage/etc_local.d_gpu_usage.start new file mode 100755 index 0000000..016e477 --- /dev/null +++ b/gpu_usage/etc_local.d_gpu_usage.start @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/sbin/gpu_usage start diff --git a/gpu_usage/etc_local.d_gpu_usage.stop b/gpu_usage/etc_local.d_gpu_usage.stop new file mode 100755 index 0000000..7c5bb3a --- /dev/null +++ b/gpu_usage/etc_local.d_gpu_usage.stop @@ -0,0 +1,3 @@ +#!/bin/bash +/usr/sbin/gpu_usage stop + diff --git a/gpu_usage/gpu_usage b/gpu_usage/gpu_usage new file mode 100755 index 0000000..80f78ae --- /dev/null +++ b/gpu_usage/gpu_usage @@ -0,0 +1,66 @@ +#!/usr/bin/python +#Formats gpu usage data from radeontop and dumps it in /tmp/gpu_usage.txt for use in conky et al. +import sys +import re +import subprocess +import signal +import os +import time + +def write_usage(text): + file_handle=open('/tmp/gpu_usage.txt','w') + file_handle.write('%s\n'%text) + file_handle.close() + +def exit(sig,frame): + sys.exit() + +def fupdate(): + try: + file_handle=open('/tmp/gpu_usage.tmp','r') + lines=file_handle.readlines() + file_handle.close() + except OSError: + write_usage('Unknown%') + return + for line in lines: + if re.match('.*gpu.*',line): + text=re.sub('.* gpu ','',line.strip()) + text=re.sub('%.*','%',text) + write_usage(text) + return + +def start(fork1): + if fork1:return + signal.signal(signal.SIGUSR1, exit)#from main script stop() + signal.signal(signal.SIGTERM, exit)#from start-stop-daemon + while True: + try: + os.remove("/tmp/gpu_usage.tmp") + except: pass + subprocess.run(['/usr/sbin/radeontop','-i1','-l1','-d','/tmp/gpu_usage.tmp'],capture_output=True) + fupdate() + #time.sleep(1) + +def stop(): + running=subprocess.run(['ps','aux'],capture_output=True,text=True) + processes=running.stdout.split('\n') + for process in processes: + if re.match('.*%s %s.*'%(sys.argv[0],'start'),process): + while process!=process.replace(' ',' '):process=process.replace(' ',' ') + pid=int(process.split(' ')[1]) + if pid != os.getpid():os.kill(pid,signal.SIGUSR1) + +try: + command=sys.argv[1] +except IndexError: + print('Usage: %s start|stop'%sys.argv[0]) + sys.exit(1) +if command=='start': + stop() + start(os.fork()) +elif command=='stop': + stop() +else: + print ('Usage: %s start|stop'%sys.argv[0]) + sys.exit(1) diff --git a/minecraft/etc_init.d_spigot b/minecraft/etc_init.d_spigot new file mode 100755 index 0000000..fc8b65e --- /dev/null +++ b/minecraft/etc_init.d_spigot @@ -0,0 +1,46 @@ +#!/sbin/openrc-run +#openrc wrapper for /usr/sbin/spigot_service +extra_commands="backup reload restart" + +depend() { + need net +} + +start() { + ebegin "Starting spigot service daemon" + start-stop-daemon --start --exec /usr/sbin/spigot_service \ + --pidfile /var/run/spigot_service.pid -- start + eend $? +} + +stop() { + ebegin "Stopping spigot service daemon" + start-stop-daemon --stop --exec /usr/sbin/spigot_service \ + --pidfile /var/run/spigot_service.pid --retry 90 -- stop + eend $? +} + +status() { + ebegin "Checking spigot service daemon status" + sleep 0.1 + /usr/sbin/spigot_service status + eend $? +} + +backup() { + ebegin "Running backup helper" + /usr/sbin/spigot_service backup + eend $? +} + +reload() { + ebegin "Reloading spigot service daemon config" + /usr/sbin/spigot_service reload + eend $? +} + +restart() { + ebegin "Restarting spigot service daemon" + /usr/sbin/spigot_service restart + eend $? +} diff --git a/minecraft/usr_sbin_spigot_service b/minecraft/usr_sbin_spigot_service new file mode 100755 index 0000000..48f7e86 --- /dev/null +++ b/minecraft/usr_sbin_spigot_service @@ -0,0 +1,200 @@ +#!/usr/bin/env python3.7 +#/usr/sbin/spigot_service +#python and screen daemonic wrapper for spigot servers +from subprocess import Popen, run +import os, sys, time, signal, shlex, re + +class server_env: + + name= 'spigot' + working_path= '/root/bukkit/' + screen_history= 4096 + world= 'Significant_Bytes' + backup_path= '/data/minecraft.backups/' + pid_file_path= '/var/run/spigot_service.pid' + exec= 'spigot.current' + options= 'nogui' + java_maxheap= 4096 + java_minheap= 1024 + thread_count= 6 + + java_command= 'java -Xmx%sM -Xms%sM -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing \ + -XX:ParallelGCThreads=%s -XX:+AggressiveOpts -jar %s %s'\ + %(java_maxheap, java_minheap, thread_count, exec, options) + +class ps_aux: + + def get_pids(invocation): + pids={} + p=run(['ps','aux'],capture_output=True,text=True) + processes=p.stdout.split('\n') + for process in processes: + if re.match('.*%s.*'%invocation, process): + pids.append(re.sub(" +"," ", process).split(' ')[1]) + return pids + + def is_running(pid): + pid=str(pid) + p=run(['ps','aux'],capture_output=True,text=True) + processes=p.stdout.split('\n') + for process in processes: + if re.match('.*%s.*'%pid, process): + if pid==re.sub(" +", " ",process).split(' ')[1]: + return True + return False + +class screen: + + def __init__(self, **kwargs): + self.name= kwargs.get('name', '') + self.window= kwargs.get('window', 0) + self.history= kwargs.get('history', 1024) + self.cwd= kwargs.get('set_wd', os.getcwd()) + self.child= None + + def create(self, command=''): + if self.child:return + cmd_string='/usr/bin/screen -h %s -DmS %s %s'%(self.history, self.name, command) + args=shlex.split(cmd_string) + self.child=Popen(args,cwd=self.cwd) + + def send(self, input=None): + if not input:return + cmd_string='/usr/bin/screen -p %s -S %s -X stuff "%s\n"'%(self.window, self.name, input) + comm_child=Popen(shlex.split(cmd_string)) + comm_child.communicate() + +class daemon: + + def start(self): + try: + with open(server_env.pid_file_path, 'r') as pid_file: + pid_file.close() + print('Error: PID file exists, exiting...') + sys.exit(1) + except OSError: + pass + child=os.fork() + if child: + with open(server_env.pid_file_path, 'x') as pid_file: + pid_file.write(str(child)) + return + #we are now the child daemon subprocess + signal.signal(signal.SIGINT, self.stop)#from ctrl-c + signal.signal(signal.SIGUSR1, self.stop)#from main script stop() + signal.signal(signal.SIGTERM, self.stop)#from start-stop-daemon + self.main_process=screen(name=server_env.name, history=server_env.screen_history, set_wd=server_env.working_path) + self.main_process.create(server_env.java_command) + self.main_process.child.communicate()#lets just hang about here + try: + os.remove(server_env.pid_file_path) + except FileNotFoundError: + pass + sys.exit(0) + + def stop(self, sig, frame): + self.main_process.send('say Server shutting down in 10 seconds') + #self.main_process.send('save-off') + #self.main_process.send('save-all') + time.sleep(5) + self.main_process.send('say Server shutting down in 5 seconds') + time.sleep(1) + self.main_process.send('say 4') + time.sleep(1) + self.main_process.send('say 3') + time.sleep(1) + self.main_process.send('say 2') + time.sleep(1) + self.main_process.send('say 1') + time.sleep(1) + self.main_process.send('say Server shutting down...') + self.main_process.send('stop') + try: + os.remove(server_env.pid_file_path) + except FileNotFoundError: + pass + #sys.exit(0) +#endclass + +def usage(): + print('Usage: %s start|stop|status|backup|reload|restart'%sys.argv[0][sys.argv[0].rfind('/')+1:]) + sys.exit() + +def start(): + main=daemon() + main.start() + +def stop(): + try: + with open(server_env.pid_file_path, 'r') as pid_file: + pid=int(pid_file.read()) + os.kill(pid, 10) + while ps_aux.is_running(pid): + time.sleep(1) + except ProcessLookupError: + print('Error: process not running, removing stale PID file') + os.remove(server_env.pid_file_path) + except FileNotFoundError: + print('Error: PID file not found') + +def status(): + try: + with open(server_env.pid_file_path, 'r') as pid_file: + pid=pid_file.read() + if ps_aux.is_running(pid): + print('World %s is running.'%server_env.world, end='',flush=True) + sys.exit(0) + else: + print('World %s is not running.'%server_env.world, end='',flush=True ) + sys.exit(1) + except FileNotFoundError: + print('World %s is not running.'%server_env.world, end='',flush=True) + sys.exit(1) + +def backup(): + print(" \033[92m*\033[0m Starting backup process ... ") + comm_process=screen(name=server_env.name) + comm_process.send('say Starting world backup...') + comm_process.send('save-off') + comm_process.send('save-all') + time.sleep(25) + backup_filename=('%s/%s-%s')%(server_env.backup_path,server_env.world,time.strftime("%Y-%m-%d_%H-%M.tar", time.gmtime())) + backup_command=shlex.split('tar -C "%s" -cf "%s" %s %s_nether %s_the_end'\ + %(server_env.working_path, backup_filename, server_env.world, server_env.world, server_env.world)) + backup_p=Popen(backup_command) + backup_p.communicate() + comm_process.send('save-on') + comm_process.send('say World backup complete.') + #print(" \033[92m*\033[0m Compressing backup ... ") + #compress_p=Popen(['xz', '-fT0', backup_filename]) + #compress_p.communicate() + print(" \033[92m*\033[0m Backup complete.") + +def reload(): + comm_process=screen(name=server_env.name) + comm_process.send('say Re-loading world configuration...') + comm_process.send('reload') + comm_process.send('say Re-load complete.') + +try: + arg=sys.argv[1] +except IndexError: + usage() + +if arg=='help': + usage() +elif arg=='start': + start() +elif arg=='stop': + stop() +elif arg=='status': + status() +elif arg=='backup': + backup() +elif arg=='reload': + reload() +elif arg=='restart': + stop() + start() +else: + usage() diff --git a/pi_temp_daemon/README.md b/pi_temp_daemon/README.md new file mode 100644 index 0000000..56bcd46 --- /dev/null +++ b/pi_temp_daemon/README.md @@ -0,0 +1,3 @@ +Temperature to fan speed daemon for Pi4 with https://www.waveshare.com/wiki/Fan_HAT + +#ToDo Write an ebuild ( yeah, right, cos that's gonna happen ;P ) diff --git a/pi_temp_daemon/etc_init.d_pitempd b/pi_temp_daemon/etc_init.d_pitempd new file mode 100755 index 0000000..59bad3a --- /dev/null +++ b/pi_temp_daemon/etc_init.d_pitempd @@ -0,0 +1,39 @@ +#!/sbin/openrc-run +extra_commands="restart monitor" + +depend(){ + need rpi-i2c +} + +start() { + ebegin "Starting pitempd daemon" + start-stop-daemon --start --exec /usr/sbin/pitempd \ + --pidfile /var/run/pitempd.pid -- start + eend $? +} + +stop() { + ebegin "Stopping pitempd daemon" + start-stop-daemon --stop --exec /usr/sbin/pitempd \ + --pidfile /var/run/pitempd.pid --signal 10 --retry 5 --stop + eend $? +} + +status() { + ebegin "Checking pitempd daemon status" + sleep 0.1 + /usr/sbin/pitempd status + eend $? +} + +restart() { + ebegin "Restarting pitempd daemon" + /usr/sbin/pitempd restart + eend $? +} + +monitor(){ + ebegin "Monitoring pitempd daemon" + /usr/sbin/pitempd monitor + eend $? +} diff --git a/pi_temp_daemon/usr_sbin_pitempd b/pi_temp_daemon/usr_sbin_pitempd new file mode 100755 index 0000000..73a2736 --- /dev/null +++ b/pi_temp_daemon/usr_sbin_pitempd @@ -0,0 +1,434 @@ +#!/usr/bin/env python + +# /***************************************************************************** +# * | File : SSD1306.py +# * | Author : Waveshare team +# * | Function : SSD1306 +# * | Info : +# *---------------- +# * | This version: V1.0 +# * | Date : 2019-11-14 +# * | Info : +# ******************************************************************************/ +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documnetation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# ^^ Included because the SSD1306 class was directly copied from the wiki code ^^ # + +from PIL import Image,ImageDraw,ImageFont +from subprocess import run +import os, sys, signal +import re, math, time +import smbus, psutil + +class PCA9685(object): + # Registers/etc. + __SUBADR1 = 0x02 + __SUBADR2 = 0x03 + __SUBADR3 = 0x04 + __MODE1 = 0x00 + __PRESCALE = 0xFE + __LED0_ON_L = 0x06 + __LED0_ON_H = 0x07 + __LED0_OFF_L = 0x08 + __LED0_OFF_H = 0x09 + __ALLLED_ON_L = 0xFA + __ALLLED_ON_H = 0xFB + __ALLLED_OFF_L = 0xFC + __ALLLED_OFF_H = 0xFD + + def __init__(self, address=0x40, debug=False): + self.bus = smbus.SMBus(1) + self.address = address + self.debug = debug + if (self.debug): + print("Reseting PCA9685") + self.write(self.__MODE1, 0x00) + + def write(self, reg, value): + "Writes an 8-bit value to the specified register/address" + self.bus.write_byte_data(self.address, reg, value) + if (self.debug): + print("I2C: Write 0x%02X to register 0x%02X" % (value, reg)) + + def read(self, reg): + "Read an unsigned byte from the I2C device" + result = self.bus.read_byte_data(self.address, reg) + if (self.debug): + print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" % (self.address, result & 0xFF, reg)) + return result + + def setPWMFreq(self, freq): + "Sets the PWM frequency" + prescaleval = 25000000.0 # 25MHz + prescaleval /= 4096.0 # 12-bit + prescaleval /= float(freq) + prescaleval -= 1.0 + if (self.debug): + print("Setting PWM frequency to %d Hz" % freq) + print("Estimated pre-scale: %d" % prescaleval) + prescale = math.floor(prescaleval + 0.5) + if (self.debug): + print("Final pre-scale: %d" % prescale) + + oldmode = self.read(self.__MODE1); + newmode = (oldmode & 0x7F) | 0x10 # sleep + self.write(self.__MODE1, newmode) # go to sleep + self.write(self.__PRESCALE, int(math.floor(prescale))) + self.write(self.__MODE1, oldmode) + time.sleep(0.005) + self.write(self.__MODE1, oldmode | 0x80) + + def setPWM(self, channel, on, off): + "Sets a single PWM channel" + self.write(self.__LED0_ON_L+4*channel, on & 0xFF) + self.write(self.__LED0_ON_H+4*channel, on >> 8) + self.write(self.__LED0_OFF_L+4*channel, off & 0xFF) + self.write(self.__LED0_OFF_H+4*channel, off >> 8) + if (self.debug): + print("channel: %d LED_ON: %d LED_OFF: %d" % (channel,on,off)) + + def setServoPulse(self, channel, pulse): + pulse = pulse*4095/100 + self.setPWM(channel, 0, int(pulse)) +#end pwm class + +class SSD1306(object): + def __init__(self, width=128, height=32, addr=0x3c): + self.width = width + self.height = height + self.Column = width + self.Page = int(height/8) + self.addr = addr + self.bus = smbus.SMBus(1) + + def SendCommand(self, cmd):# write command + self.bus.write_byte_data(self.addr, 0x00, cmd) + + def SendData(self, cmd):# write ram + self.bus.write_byte_data(self.addr, 0x40, cmd) + + def Closebus(self): + self.bus.close() + + def Init(self): + self.SendCommand(0xAE) + + self.SendCommand(0x40) # set low column address + self.SendCommand(0xB0) # set high column address + + self.SendCommand(0xC8) # not offset + + self.SendCommand(0x81) + self.SendCommand(0xff) + + self.SendCommand(0xa1) + + self.SendCommand(0xa6) + + self.SendCommand(0xa8) + self.SendCommand(0x1f) + + self.SendCommand(0xd3) + self.SendCommand(0x00) + + self.SendCommand(0xd5) + self.SendCommand(0xf0) + + self.SendCommand(0xd9) + self.SendCommand(0x22) + + self.SendCommand(0xda) + self.SendCommand(0x02) + + self.SendCommand(0xdb) + self.SendCommand(0x49) + + self.SendCommand(0x8d) + self.SendCommand(0x14) + + self.SendCommand(0xaf) + + def ClearBlack(self): + for i in range(0, self.Page): + self.SendCommand(0xb0 + i) + self.SendCommand(0x00) + self.SendCommand(0x10) + for j in range(0, self.Column): + self.SendData(0x00) + + def ClearWhite(self): + for i in range(0, self.Page): + self.SendCommand(0xb0 + i) + self.SendCommand(0x00) + self.SendCommand(0x10) + for j in range(0, self.Column): + self.SendData(0xff) + + def getbuffer(self, image): + buf = [0xff] * (self.Page * self.Column) + image_monocolor = image.convert('1') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + if(imwidth == self.width and imheight == self.height): + # print ("Horizontal screen") + for y in range(imheight): + for x in range(imwidth): + # Set the bits for the column of pixels at the current position. + if pixels[x, y] == 0: + buf[x + int(y / 8) * self.width] &= ~(1 << (y % 8)) + elif(imwidth == self.height and imheight == self.width): + # print ("Vertical screen") + for y in range(imheight): + for x in range(imwidth): + newx = y + newy = self.height - x - 1 + if pixels[x, y] == 0: + buf[(newx + int(newy / 8 )*self.width) ] &= ~(1 << (y % 8)) + for x in range(self.Page * self.Column): + buf[x] = ~buf[x] + return buf + + def ShowImage(self, pBuf): + for i in range(0, self.Page): + self.SendCommand(0xB0 + i) # set page address + self.SendCommand(0x00) # set low column address + self.SendCommand(0x10) # set high column address + # write data # + for j in range(0, self.Column): + self.SendData(pBuf[j+self.width*i]) +#end oled class + + +#start of #mycode +class ps: + + def get_pids(invocation): + pids=[] + p=run(['ps','aux'],capture_output=True,text=True) + processes=p.stdout.split('\n') + for process in processes: + if re.match('.*%s.*'%invocation, process): + pids.append(int(re.sub(" +"," ", process).split(' ')[1])) + return pids + + def is_running(pid): + pid=str(pid) + p=run(['ps','aux'],capture_output=True,text=True) + processes=p.stdout.split('\n') + for process in processes: + if re.match('.*%s.*'%pid, process): + if pid==re.sub(" +", " ",process).split(' ')[1]: + return True + return False +#end ps class + +class daemon: + pid_file_path='/var/run/pitempd.pid' + fan_speed_path='/var/run/pitempd.pwm' + cpu_temp_path='/sys/class/hwmon/hwmon0/temp1_input' + fan_disable_temp=45 + + default_fan_speed=0 + fan_min_speed=40 + fan_max_speed=100 + update_time=2.5 + debug=True + + def __init__(self): + self.pwm=PCA9685(0x40, debug=False) + self.pwm.setPWMFreq(50) + self.pwm.setServoPulse(0,100) + self.oled = SSD1306() + self.oled.Init() + self.oled.ClearBlack() + self.image1 = Image.new('1', (self.oled.width, self.oled.height), "WHITE") + self.draw = ImageDraw.Draw(self.image1) + self.font = ImageFont.load_default() + + def curve(self, x): + if x <= self.fan_disable_temp: + return self.default_fan_speed + #y = (((x−40)/5.5)^2.4)+40 (curve from Kmplot) + y=(((x-self.fan_disable_temp)/5.5)**2.4)+self.fan_min_speed + if y > self.fan_max_speed: + y=self.fan_max_speed + return y + + def start(self): + try: + with open(self.pid_file_path, 'r') as pid_file: + pid_file.close() + print('Error: PID file exists, exiting...') + sys.exit(1) + except OSError: + pass + child=os.fork() + if child: + with open(self.pid_file_path, 'x') as pid_file: + pid_file.write(str(child)) + return + signal.signal(signal.SIGINT, self.stop)#from ctrl-c + signal.signal(signal.SIGUSR1, self.stop)#from main script stop() + signal.signal(signal.SIGTERM, self.stop)#from start-stop-daemon + #Main loop + top_line=True + while True: + if top_line: + cpu_string='CPU Usage:' + cpu_stat='%s%%'%int(psutil.cpu_percent(interval=self.update_time)) + else: + cpu_string='CPU Speed:' + cpu_stat='%sMHz'%int(psutil.cpu_freq().current) + time.sleep(self.update_time) + top_line=not top_line + temp=self.get_temp() + fan=self.curve(temp) + with open(self.fan_speed_path, 'w') as pwm_file: + pwm_file.write('%.1f%%\n'%fan) + self.set_fan(fan) + self.set_display( cpu_string,cpu_stat, \ + 'CPU Temp:', '%.1f°C'%temp, \ + 'Fan Speed:', '%.1f%%'%fan) + + def get_temp(self): + with open(self.cpu_temp_path, 'r') as temp_file: + temp=int(temp_file.read())/1000 + return temp + + def set_fan(self,speed): + self.pwm.setServoPulse(0,speed) + + def set_display(self,upper_left, upper_right,mid_left, mid_right, lower_left='test', lower_right='test'): + self.draw.rectangle((0,0,128,32), fill = 1) + self.draw.text((0,0), upper_left, font=self.font, fill = 0) + self.draw.text((85,0), upper_right, font=self.font, fill = 0) + self.draw.text((0,11), mid_left, font=self.font, fill = 0) + self.draw.text((85,11), mid_right, font=self.font, fill = 0) + self.draw.text((0,22), lower_left, font=self.font, fill = 0) + self.draw.text((85,22), lower_right, font=self.font, fill = 0) + self.oled.ShowImage(self.oled.getbuffer(self.image1.rotate(180))) + + def stop(self, sig, frame): + self.set_fan(self.default_fan_speed) + with open(self.fan_speed_path, 'w') as pwm_file: + pwm_file.write('%.1f%%\n'%self.default_fan_speed) + self.draw.rectangle((0,0,128,32), fill = 1) + self.draw.text((40,0),'Daemon', font=self.font, fill = 0) + self.draw.text((38,11),'Offline', font=self.font, fill = 0) + self.draw.text((0,22), 'Fan Speed:', font=self.font, fill = 0) + self.draw.text((85,22), '%.1f%%'%self.default_fan_speed, font=self.font, fill = 0) + self.oled.ShowImage(self.oled.getbuffer(self.image1.rotate(180))) + self.oled.Closebus() + try: + os.remove(daemon.pid_file_path) + except FileNotFoundError: + pass + sys.exit(0) + +#end daemon class + +def usage(): + print('Usage: %s start|stop|status|monitor|restart'%sys.argv[0][sys.argv[0].rfind('/')+1:]) + sys.exit() + +def start(): + main=daemon() + main.start() + +def stop(): + try: + with open(daemon.pid_file_path, 'r') as pid_file: + pid=int(pid_file.read()) + os.kill(pid, 10) + while ps.is_running(pid): time.sleep(1) + except ProcessLookupError: + print('Error: process not running, removing stale PID file') + os.remove(daemon.pid_file_path) + except FileNotFoundError: + print('Error: PID file not found, checking for process...', end='',flush=True) + pids=ps.get_pids('%s start'%sys.argv[0]) + if pids: + for pid in pids: + print(' killing process: %s'%pid) + os.kill(pid, 10) + while ps.is_running(pid): time.sleep(1) + else: + print(' daemon not running.') + sys.exit(0) + +def status(): + try: + with open(daemon.pid_file_path, 'r') as pid_file: + pid=pid_file.read() + if ps.is_running(pid): + sys.exit(0) + else: + sys.exit(1) + except FileNotFoundError: + sys.exit(1) + +def monstop(sig, f): + print('Exiting: %s'%sig) + sys.exit(0) + +def monitor(): + signal.signal(signal.SIGINT, monstop)#from ctrl-c + signal.signal(signal.SIGUSR1, monstop)#from main script stop() + signal.signal(signal.SIGTERM, monstop)#from start-stop-daemon + cpu_usage='Waiting...' + while True: + with open(daemon.cpu_temp_path, 'r') as temp_file: + temp=int(temp_file.read())/100 + with open(daemon.fan_speed_path, 'r') as pwm_file: + str=pwm_file.read() + pwm=float(str[:-2]) + try: + with open(daemon.pid_file_path, 'r') as pid_file: + pid=pid_file.read() + except FileNotFoundError: + pid='Not running' + cpu_mhz='%sMHz'%int(psutil.cpu_freq().current) + print('Daemon PID:',pid) + print('CPU Speed: ',cpu_mhz) + print('CPU Usage: ',cpu_usage) + print('CPU Temp: ','%s°C'%(int(temp)/10)) + print('Fan Speed: ','%.1f%%'%pwm) + print() + cpu_usage='%s%%'%int(psutil.cpu_percent(interval=daemon.update_time)) + +try: + arg=sys.argv[1] +except IndexError: + usage() + +if arg=='help': + usage() +elif arg=='start': + start() +elif arg=='stop': + stop() +elif arg=='status': + status() +elif arg=='restart': + stop() + start() +elif arg=='monitor': + monitor() +else: + usage() diff --git a/python_3.9_compat/python3_9-py-checker b/python_3.9_compat/python3_9-py-checker new file mode 100755 index 0000000..bd47a1c --- /dev/null +++ b/python_3.9_compat/python3_9-py-checker @@ -0,0 +1,119 @@ +#!/bin/bash +# check the files generated by the python_3_9_compat.sh script that crawls the portage tree +# usage python3_9-py-checker +log_file="/run/user/$UID/pycheker.log" +#stolen from something in ~/bin/ +prog=('\' '|' '/' '-' 'done!') +prog_ind=0 +function progress(){ + echo -ne "\033[1K\r$* ${prog[${prog_ind}]}" + (( ++ prog_ind )) + [ ${prog_ind} -gt 3 ] && prog_ind=0 +} +function end_progress(){ + echo -e "\033[1K\r$* ${prog[4]}" +} +#end-stolen +function log(){ + echo "DEBUG: $1 failed due to $2" >> "${log_file}" + return 0 +} +echo -n > "${log_file}" +safelist="" +for ebuild in $* +do + echo -n "Running: ebuild ${ebuild} prepare" + workdir=$(USE="python_single_target_python3_8 python_targets_python3_8" ebuild "${ebuild}" prepare 2>&1 |tee -a "${log_file}"|awk '/Preparing source in/{print $5};/Remove.*\.prepared/{print $3}') || break + workdir=${workdir#\'} + workdir=${workdir%.prepared\'} + accept=true + echo " done!" + if [ -d "${workdir}" ] + then + while read file + do + progress "Checking py files for ${ebuild}" + + error="__import__() now raises ImportError instead of ValueError" + awk '/try:/{intry=1;impused=0};/__import__/ && intry{impused=1};intry && impused{print};/except|finally:/{intry=0}' "${file}" | grep -q "ValueError" && accept=false && log "$ebuild" "$error" && break + + error="importlib.util.resolve_name() now raise ImportError" + grep -qw "importlib" "$file" && awk '/try:/{intry=1;impused=0};/resolve_name/{impused=1};intry && impused{print};/except|finally:/{intry=0}' "${file}" | grep -q "ValueError" && accept=false && log "$ebuild" "$error" && break + + error="The venv activation scripts no longer special-case when __VENV_PROMPT__ is set to ""." + grep -q "from.*venv.*import\|import.*venv" "$file" && grep -q "__VENV_PROMPT__" "$file" && accept=false && log "$ebuild" "$error" && break + #it's set by default to non null, we only have to find it being reassigned. + + #error="The compresslevel parameter of bz2.BZ2File became keyword-only" + grep -q "from.*bz2.*import\|import.*bz2" "$file" && grep -q "BZ2File" "$file"|grep -qv "compresslevel=" && accept=false && log "$ebuild" "$error" && break + #catching references + + error="Simplified AST for subscription." + grep -q "from.*ast.*import\|import.*ast" "$file" && grep -q "issubclass\|visit_Num" "$file" && accept=false && log "$ebuild" "$error" && break #lots of manual checking needed + + error="The encoding parameter has been added to the classes ftplib.FTP and ftplib.FTP_TLS" + grep -q "from.*ftplib.*import\|import.*ftplib" "$file" && grep -q "FTP\|FTP_TLS" "$file" && accept=false && log "$ebuild" "$error" && break + + error="asyncio.loop.shutdown_default_executor() has been added to AbstractEventLoop" + grep -q "from.*asyncio.*import\|import.*asyncio" "$file" && grep -q "class.*(.*loop):" "$file" && accept=false && log "$ebuild" "$error" && break + #need to refine this to instances only, unless it's inherited we don't care + + error="The logging.getLogger() API now returns the root logger when passed the name 'root'" #careful, possible security issue + grep -q "from.*logging.*import\|import.*logging" "$file" && grep -q "getLogger(.*'root'.*)" "$file" && accept=false && log "$ebuild" "$error" && break + #directly exclude getLogger('root') calls + grep -q "from.*logging.*import\|import.*logging" "$file" && grep -qv "getLogger(.*'" "$file"| grep -q "getLogger" && accept=false && log "$ebuild" "$error" && break + #don't exclude if getLogger is called directly with a static name, but exclude variable and referenced calls to getLogger + + error="Division handling of PurePath now returns NotImplemented instead of raising a TypeError" + grep -q "from.*pathlib.*import\|import.*pathlib" "$file" && grep -q "PurePath" "$file" && grep -q "TypeError" "$file" && accept=false && log "$ebuild" "$error" && break + #may need to awk this... + + error="Starting with Python 3.9.5 the ipaddress module no longer accepts any leading zeros in IPv4 address strings." + grep -q "from.*ipaddress.*import\|import.*ipaddress" "$file" && grep -q "IPv4Address\|IPv4Network\|IPv4Interface\|collapse_addresses\|ip_address\|ip_interface\|ip_network\|summarize_address_range" "$file" && accept=false && log "$ebuild" "$error" && break + #Much grief :( + + error="codecs.lookup() now normalizes the encoding name" + grep -q "from.*codecs.*import\|import.*codecs" "$file" && grep -q "lookup" "$file" && accept=false && log "$ebuild" "$error" && break + #much pain to check for :( should exclude for expediency and let upstream -> upstream sort it + + done < <(find "${workdir}" -iname '*.py') + end_progress "Checking py files for ${ebuild}" + while read file + do + progress "Checking C files for ${ebuild}" + + error="PyInterpreterState.eval_frame (PEP 523) now requires a new mandatory tstate parameter" + grep -q "PyInterpreterState" "$file" && grep -q "eval_frame" "$file" && accept=false && log "$ebuild" "$error" && break + + error="Extension modules: m_traverse, m_clear and m_free functions of PyModuleDef are no longer called" + grep -q "PyModuleDef" "$file" && "$file" && accept=false && log "$ebuild" "$error" && break + + error="Removed _PyRuntime.getframe hook and removed _PyThreadState_GetFrame also PyThreadFrameGetter" + grep -q "_PyRuntime" "$file" && grep -q "getframe" "$file" && accept=false && log "$ebuild" "$error" && break + grep -q " _PyThreadState_GetFrame\|PyThreadFrameGetter" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed PyAsyncGen_ClearFreeLists() PyContext_ClearFreeList() PyDict_ClearFreeList() PyFloat_ClearFreeList()" + grep -q "PyAsyncGen_ClearFreeLists\|PyContext_ClearFreeList\|PyDict_ClearFreeList\|PyFloat_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed PyFrame_ClearFreeList() PyList_ClearFreeList() PyMethod_ClearFreeList() PyCFunction_ClearFreeList() " + grep -q "PyFrame_ClearFreeList\|PyList_ClearFreeList\|PyMethod_ClearFreeList\|PyCFunction_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed PySet_ClearFreeList() PyTuple_ClearFreeList() PyUnicode_ClearFreeList()" + grep -q "PySet_ClearFreeList\|PyTuple_ClearFreeLis\|PyUnicode_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed PyBytes_InsertThousandsGroupingLocale, _PyBytes_InsertThousandsGrouping, _Py_InitializeFromArgs" + grep -q "PyBytes_InsertThousandsGroupingLocale\|_PyBytes_InsertThousandsGrouping\|_Py_InitializeFromArgs" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed _Py_InitializeFromWideArgs, _PyFloat_Repr, _PyFloat_Digits, _PyFloat_DigitsInit, PyFrame_ExtendStack, " + grep -q "_Py_InitializeFromWideArgs\|_PyFloat_Repr\|_PyFloat_Digits\|PyFrame_ExtendStack" "$file" && accept=false && log "$ebuild" "$error" && break + + error="removed PyNullImporter_Type, PyCmpWrapper_Type, PySortWrapper_Type, PyNoArgsFunction _PyAIterWrapper_Type," + grep -q "PyNullImporter_Type\|PyCmpWrapper_Type\|PySortWrapper_Type\|PyNoArgsFunction\|_PyAIterWrapper_Type" "$file" && accept=false && log "$ebuild" "$error" && break + done < <(find "${workdir}" -regex "*.\.[c,h,cpp]") + end_progress "Checking C files for ${ebuild}" + $accept && safelist="${safelist} ${ebuild}" + fi +done + +echo -e "${safelist// /\\n}\nare safe to add 3_9 support without patching" + diff --git a/python_3.9_compat/python3_9-py-logger b/python_3.9_compat/python3_9-py-logger new file mode 100755 index 0000000..d3f73e0 --- /dev/null +++ b/python_3.9_compat/python3_9-py-logger @@ -0,0 +1,120 @@ +#!/bin/bash +# Check the files generated by the python_3_9_compat.sh script that crawls the portage tree, and log the failure points +# The other script exits the source code path on first failure and moves on, this one doesn't +# usage python3_9-py-checker +log_file="/run/user/$UID/pylogger.log" +#stolen from something in ~/bin/ +prog=('\' '|' '/' '-' 'done!') +prog_ind=0 +function progress(){ + echo -ne "\033[1K\r$* ${prog[${prog_ind}]}" + (( ++ prog_ind )) + [ ${prog_ind} -gt 3 ] && prog_ind=0 +} +function end_progress(){ + echo -e "\033[1K\r$* ${prog[4]}" +} +#end-stolen +function log(){ + echo "DEBUG: $1 failed due to $2" >> "${log_file}" + return 0 +} +echo -n > "${log_file}" +safelist="" +for ebuild in $* +do + echo -n "Running: ebuild ${ebuild} prepare" + workdir=$(USE="python_single_target_python3_8 python_targets_python3_8" ebuild "${ebuild}" prepare 2>&1 |awk '/Preparing source in/{print $5};/Remove.*\.prepared/{print $3}') || break + workdir=${workdir#\'} + workdir=${workdir%.prepared\'} + echo " done!" + if [ -d "${workdir}" ] + then + accept=true + while read file + do + progress "Checking py files for ${ebuild}" + + error="__import__() now raises ImportError instead of ValueError" + awk '/try:/{intry=1;impused=0};/__import__/ && intry{impused=1};intry && impused{print};/except|finally:/{intry=0}' "${file}" | grep -q "ValueError" && accept=false && log "$ebuild" "$error" #&& break + + error="importlib.util.resolve_name() now raise ImportError" + grep -qw "importlib" "$file" && awk '/try:/{intry=1;impused=0};/resolve_name/{impused=1};intry && impused{print};/except|finally:/{intry=0}' "${file}" | grep -q "ValueError" && accept=false && log "$ebuild" "$error" #&& break + + error="The venv activation scripts no longer special-case when __VENV_PROMPT__ is set to ""." + grep -q "from.*venv.*import\|import.*venv" "$file" && grep -q "__VENV_PROMPT__" "$file" && accept=false && log "$ebuild" "$error" #&& break + #it's set by default to non null, we only have to find it being reassigned. + + #error="The compresslevel parameter of bz2.BZ2File became keyword-only" + grep -q "from.*bz2.*import\|import.*bz2" "$file" && grep -q "BZ2File" "$file"|grep -qv "compresslevel=" && accept=false && log "$ebuild" "$error" #&& break + #catching references + + error="Simplified AST for subscription." + grep -q "from.*ast.*import\|import.*ast" "$file" && grep -q "issubclass\|visit_Num" "$file" && accept=false && log "$ebuild" "$error" #&& break #lots of manual checking needed + + error="The encoding parameter has been added to the classes ftplib.FTP and ftplib.FTP_TLS" + grep -q "from.*ftplib.*import\|import.*ftplib" "$file" && grep -q "FTP\|FTP_TLS" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="asyncio.loop.shutdown_default_executor() has been added to AbstractEventLoop" + grep -q "from.*asyncio.*import\|import.*asyncio" "$file" && grep -q "class.*(.*loop):" "$file" && accept=false && log "$ebuild" "$error" #&& break + #need to refine this to instances only, unless it's inherited we don't care + + error="The logging.getLogger() API now returns the root logger when passed the name 'root'" #careful, possible security issue + grep -q "from.*logging.*import\|import.*logging" "$file" && grep -q "getLogger(.*'root'.*)" "$file" && accept=false && log "$ebuild" "$error" #&& break + #directly exclude getLogger('root') calls + grep -q "from.*logging.*import\|import.*logging" "$file" && grep -qv "getLogger(.*'" "$file"| grep -q "getLogger" && accept=false && log "$ebuild" "$error" #&& break + #don't exclude if getLogger is called directly with a static name, but exclude variable and referenced calls to getLogger + + error="Division handling of PurePath now returns NotImplemented instead of raising a TypeError" + grep -q "from.*pathlib.*import\|import.*pathlib" "$file" && grep -q "PurePath" "$file" && grep -q "TypeError" "$file" && accept=false && log "$ebuild" "$error" #&& break + #may need to awk this... + + error="Starting with Python 3.9.5 the ipaddress module no longer accepts any leading zeros in IPv4 address strings." + grep -q "from.*ipaddress.*import\|import.*ipaddress" "$file" && grep -q "IPv4Address\|IPv4Network\|IPv4Interface\|collapse_addresses\|ip_address\|ip_interface\|ip_network\|summarize_address_range" "$file" && accept=false && log "$ebuild" "$error" #&& break + #Much grief :( + + error="codecs.lookup() now normalizes the encoding name" + grep -q "from.*codecs.*import\|import.*codecs" "$file" && grep -q "lookup" "$file" && accept=false && log "$ebuild" "$error" #&& break + #much pain to check for :( should exclude for expediency and let upstream -> upstream sort it + + done < <(find "${workdir}" -iname '*.py') + end_progress "Checking py files for ${ebuild}" + while read file + do + progress "Checking C files for ${ebuild}" + + error="PyInterpreterState.eval_frame (PEP 523) now requires a new mandatory tstate parameter" + grep -q "PyInterpreterState" "$file" && grep -q "eval_frame" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="Extension modules: m_traverse, m_clear and m_free functions of PyModuleDef are no longer called" + grep -q "PyModuleDef" "$file" && "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="Removed _PyRuntime.getframe hook and removed _PyThreadState_GetFrame also PyThreadFrameGetter" + grep -q "_PyRuntime" "$file" && grep -q "getframe" "$file" && accept=false && log "$ebuild" "$error" #&& break + grep -q " _PyThreadState_GetFrame\|PyThreadFrameGetter" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed PyAsyncGen_ClearFreeLists() PyContext_ClearFreeList() PyDict_ClearFreeList() PyFloat_ClearFreeList()" + grep -q "PyAsyncGen_ClearFreeLists\|PyContext_ClearFreeList\|PyDict_ClearFreeList\|PyFloat_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed PyFrame_ClearFreeList() PyList_ClearFreeList() PyMethod_ClearFreeList() PyCFunction_ClearFreeList() " + grep -q "PyFrame_ClearFreeList\|PyList_ClearFreeList\|PyMethod_ClearFreeList\|PyCFunction_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed PySet_ClearFreeList() PyTuple_ClearFreeList() PyUnicode_ClearFreeList()" + grep -q "PySet_ClearFreeList\|PyTuple_ClearFreeLis\|PyUnicode_ClearFreeList" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed PyBytes_InsertThousandsGroupingLocale, _PyBytes_InsertThousandsGrouping, _Py_InitializeFromArgs" + grep -q "PyBytes_InsertThousandsGroupingLocale\|_PyBytes_InsertThousandsGrouping\|_Py_InitializeFromArgs" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed _Py_InitializeFromWideArgs, _PyFloat_Repr, _PyFloat_Digits, _PyFloat_DigitsInit, PyFrame_ExtendStack, " + grep -q "_Py_InitializeFromWideArgs\|_PyFloat_Repr\|_PyFloat_Digits\|PyFrame_ExtendStack" "$file" && accept=false && log "$ebuild" "$error" #&& break + + error="removed PyNullImporter_Type, PyCmpWrapper_Type, PySortWrapper_Type, PyNoArgsFunction _PyAIterWrapper_Type," + grep -q "PyNullImporter_Type\|PyCmpWrapper_Type\|PySortWrapper_Type\|PyNoArgsFunction\|_PyAIterWrapper_Type" "$file" && accept=false && log "$ebuild" "$error" #&& break + done < <(find "${workdir}" -regex "*.\.[c,h,cpp]") + end_progress "Checking C files for ${ebuild}" + $accept && safelist="${safelist} ${ebuild}" + fi +done + +echo -e "${safelist// /\\n}\nare safe to add 3_9 support without patching" + diff --git a/python_3.9_compat/python_3_9_compat.sh b/python_3.9_compat/python_3_9_compat.sh new file mode 100755 index 0000000..0175124 --- /dev/null +++ b/python_3.9_compat/python_3_9_compat.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# 3.9_compat-2.sh build lists of ebuilds that need updating for python3_9 compatability +# stuff that's maybe worth altering +[ -d "${REPO_PATH}" ] ||\ +REPO_PATH="/var/db/repos/updating" +[ -z "${ARCH}" ] &&\ +ARCH="amd64" +base_path="/run/user/${UID}/py-3_9-compat-v2.${REPO_PATH##*/}" +# stuff that's not worth altering +stable_list="${base_path}.stable.list" +testing_list="${base_path}.testing.list" +wip_list="${base_path}.wip.list" +considerlist="${base_path}.maybe-wip.list" +commands=$* +message="" +function finish { + tput cnorm + echo -e "$message" +} +trap finish EXIT +#stolen from something in ~/bin/ +prog=('\' '|' '/' '-' 'done!') +prog_ind=0 +function progress(){ + echo -ne "\033[1K\r$* ${prog[${prog_ind}]}" + (( ++ prog_ind )) + [ ${prog_ind} -gt 3 ] && prog_ind=0 +} +function end_progress(){ + echo -e "\033[1K\r$* ${prog[4]}" +} +#end-stolen +function build(){ #create a list of all ebuilds as a starting base + rm -f "${base_path}"*list + progress "Building master ebuild lists" + find "${REPO_PATH}/" -mindepth 3 -maxdepth 3 -name '*.ebuild' -a ! -name '*9999*' ! -iname '*-[0-9]*alpha*'|xargs grep -lw "PYTHON_COMPAT" -- |xargs grep -lw "KEYWORD.*~${ARCH}" -- >"${testing_list}.tmp" + progress "Building master ebuild lists" + sort -Vr "${testing_list}.tmp" > "${testing_list}" && rm -f "${testing_list}.tmp" + progress "Building master ebuild lists" + find "${REPO_PATH}/" -mindepth 3 -maxdepth 3 -name '*.ebuild' -a ! -name '*9999*' ! -iname '*-[0-9]*alpha*'|xargs grep -lw "PYTHON_COMPAT" -- |xargs grep -lw "KEYWORD.* ${ARCH}\|KEYWORD.*\"${ARCH}" -- >"${stable_list}.tmp" + progress "Building master ebuild lists" + sort -Vr "${stable_list}.tmp" > "${stable_list}" && rm -f "${stable_list}.tmp" + end_progress "Building master ebuild lists" +} +function filter_list(){ + while read ebuild + do + progress "Filtering compatible packages in ${1}" + atompath="${ebuild%-[0-9]*}";atompath="${atompath//\//\\/}" + if grep "python3_" ${ebuild}|grep -q "3_9\|,9\|\.\.9\|\.\.10" + then + [[ "${2}" == "do_wip" ]] && echo $ebuild >> $wip_list + sed -i "/${atompath}/d" "${1}" + else + sed -i "0,/${atompath}/{s/${atompath}/RESTORE_ME/};/${atompath}-[0-9].*/d;s/RESTORE_ME/${atompath}/" ${1} + fi + done < "${1}" +} +function filter_stable(){ #filter the compatible ebuilds from the stable_list + filter_list "${stable_list}" + end_progress "Filtering compatible packages in ${stable_list}" + [ -f $stable_list ] && message="${message}\nList of $(wc -l < ${stable_list}) non-compatible packages in: $stable_list" +} +function filter_testing(){ #filter the compatible ebuilds from the testing_list, build a compatible ebuilds list to further filter stable_list later + filter_list "${testing_list}" "do_wip" + end_progress "Filtering compatible packages in ${testing_list}" + [ -f $testing_list ] && message="${message}\nList of $(wc -l < ${testing_list}) non-compatible packages in: $testing_list" +} +function filter_wip(){ #remove duplicates package atoms + while read ebuild + do + progress "Filtering duplicate wip packages" + atompath="${ebuild%-[0-9]*}" + atompath="${atompath//\//\\/}" + sed -i "0,/${atompath}/{s/${atompath}/RESTORE_ME/};/${atompath}-[0-9].*/d;s/RESTORE_ME/${atompath}/" ${wip_list} + done < "${wip_list}" + end_progress "Filtering duplicate wip packages" +} +function check_wip(){ #filter the stable_list and log changes + echo -n >"${considerlist}" + for ebuild in $(grep -e "-r[0-9][0-9]*.ebuild" ${wip_list}) + do + progress "Checking for wip packages" + [[ "$ebuild" =~ (.*)-r([0-9]*[0-9]).ebuild ]] + revision="${BASH_REMATCH[2]}" + (( -- revision )) + if [ $revision -gt 0 ] + then #look for a previous revision + temp=${revision:1} + revision=${revision:${#temp}} + poss_ebuild=$(echo "$ebuild"|sed "s/\(.*-r[0-9]*\)[0-9].ebuild/\1[0-9]*[0-$revision].ebuild/") + else #look for an unrevised similar version + poss_ebuild=$(echo "$ebuild"|sed "s/\(.*\)-r[0-9]*[0-9].ebuild/\1.ebuild/") + fi + poss_fix=$(grep "${poss_ebuild}" ${stable_list})&&\ + echo "$(echo ${ebuild}|sed 's/.*\/\(.*\/.*\/.*\)/\1/') seems to be a fix for $(echo ${poss_fix}|sed 's/.*\/\(.*\/.*\/.*\)/\1/')" >>"${considerlist}" &&\ + sed_fix=$(echo ${poss_fix%-[0-9]*}|sed 's/\//\\\//g')&&\ + sed -i "/${sed_fix}-[0-9].*/d" ${stable_list} + done + end_progress "Checking for wip packages" + if [ -f $considerlist ] + then + message="\nList of $(wc -l <${considerlist}) already fixed stable packages in: $considerlist${message}" + echo -e "\n\n*** The above packages have been removed from ${stable_list} ***" >>$considerlist + echo "*** This file is for logging purposes only. ***" >>$considerlist + fi +} +function all(){ #do everything + build + filter_testing + filter_stable + filter_wip + check_wip +} +function main(){ #cheesy hack for now... + for command in $commands + do + $command + done +} +function usage(){ #need to expand + echo -e "Usage: ${0##*/} + Where is one or more of [build|filter_testing|filter_stable|filter_wip|check_wip] + Use commands in the shown order, as each is dependant on the previous. + The special command [all] can be used to run a full scan and show results. + REPO_PATH (default /var/db/repos/gentoo) and ARCH (default amd64) can be set on the command line, e.g.\n + REPO_PATH=\"/usr/aarch64-unknown-linux-gnu/var/db/repos/gentoo\" ARCH=\"arm64\" ${0##*/} all\n" +} +if [ $# -gt 0 ] #do shit +then + tput civis + main +else + usage +fi + diff --git a/random_scripts/TV-On b/random_scripts/TV-On new file mode 100755 index 0000000..77131dd --- /dev/null +++ b/random_scripts/TV-On @@ -0,0 +1,6 @@ +#!/bin/bash +#Force monitor into existance because X won't do as it's told. +xrandr --setmonitor +HDMI-A-0 1920/531x1080/299+1920+0 HDMI-A-0 +xrandr --newmode "TVMode" 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync +xrandr --addmode HDMI-A-0 TVMode +xrandr --output HDMI-A-0 --mode TVMode --right-of DisplayPort-0 diff --git a/random_scripts/etc_local.d_nfs_mounts.stopper b/random_scripts/etc_local.d_nfs_mounts.stopper new file mode 100755 index 0000000..58faddc --- /dev/null +++ b/random_scripts/etc_local.d_nfs_mounts.stopper @@ -0,0 +1,26 @@ +#!/bin/bash +#Reads /proc/mounts and performs a lazy, forced un-mount of any nfs file systems if the server does not respond to ping +cat /proc/mounts >/tmp/NFSumount_mounts.tmp + +DEBUG=false +PRETEND=false + +while read line;do + if ! echo $line |awk '{print $3}'| grep -wq "nfs4\?";then + continue + fi + mountpoint=$(echo ${line}|awk '{print $2}') + if $DEBUG;then echo -en "NFS mount at ${mountpoint} found, ";fi + server=$(echo ${line}|grep -wo "addr=[0-2]\?[0-9]\?[0-9]\.[0-2]\?[0-9]\?[0-9]\.[0-2]\?[0-9]\?[0-9]\.[0-2]\?[0-9]\?[0-9]"|sed 's/addr=//') + if $DEBUG;then echo -en "server is ${server}. ";fi + if ! ping -w5 -i0.2 -c10 ${server} >/dev/null;then + if $DEBUG;then echo -ne "$server Did not respond to ping. ";fi + echo "Unmounting \"${mountpoint}\"" + if ! $PRETEND;then umount -fl ${mountpoint};fi + else + if $DEBUG; then echo $server responded to ping;fi + fi + +done < /tmp/NFSumount_mounts.tmp + +rm /tmp/NFSumount_mounts.tmp diff --git a/random_scripts/etc_local.d_soundcard.start b/random_scripts/etc_local.d_soundcard.start new file mode 100755 index 0000000..d6031a4 --- /dev/null +++ b/random_scripts/etc_local.d_soundcard.start @@ -0,0 +1,15 @@ +#!/bin/sh +#redirect soundcard outputs on 'admin' host +#generated by hdajackretask from media-sound/alsa-tools +echo "0x12 0x411111f0" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x14 0x01014010" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x15 0x01011012" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x16 0x01016011" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x17 0x40170000" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x18 0x01a19040" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x19 0x02a19050" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x1a 0x0181304f" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x1b 0x01014013" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x1d 0x40e7e629" > /sys/class/sound/hwC1D0/user_pin_configs +echo "0x1e 0x01456130" > /sys/class/sound/hwC1D0/user_pin_configs +echo 1 > /sys/class/sound/hwC1D0/reconfig diff --git a/random_scripts/etc_local.d_tcp_syn_retries.stop b/random_scripts/etc_local.d_tcp_syn_retries.stop new file mode 100755 index 0000000..767041a --- /dev/null +++ b/random_scripts/etc_local.d_tcp_syn_retries.stop @@ -0,0 +1,4 @@ +#!/bin/bash +#The polite way of cutting down on "Unounting network filesystems", deprecates nfs_mounts.stop +echo 1 > /proc/sys/net/ipv4/tcp_syn_retries + diff --git a/random_scripts/shebang_test.py b/random_scripts/shebang_test.py new file mode 100755 index 0000000..9ba6d5e --- /dev/null +++ b/random_scripts/shebang_test.py @@ -0,0 +1,6 @@ +#!/usr/bin/python +#see what the actual commandline ues to invoke python is... +import os,sys +with open('/proc/%s/cmdline'%os.getpid(),'r') as file:cll=file.read().split('\x00') +print('Does "/usr/bin/python" match "%s"?'%' '.join(cll[0:cll.index(sys.argv[0])])) + diff --git a/random_scripts/speech.sh b/random_scripts/speech.sh new file mode 100755 index 0000000..367ad58 --- /dev/null +++ b/random_scripts/speech.sh @@ -0,0 +1,6 @@ +#!/bin/bash +#use google translate to convert text to speech +rm /tmp/speech.ogg +say() { local IFS=+;ffmpeg -i "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=$*&tl=en" /tmp/speech.ogg; } +say $* +ogg123 /tmp/speech.ogg diff --git a/random_scripts/ytplay b/random_scripts/ytplay new file mode 100755 index 0000000..99ab9ad --- /dev/null +++ b/random_scripts/ytplay @@ -0,0 +1,16 @@ +#!/bin/bash +#for livestream event viewing multiple streams, dump urls into the commandline, look at the pritty videos :) +urls=$* +for w in ${urls};do +url=$(echo "${w}" |sed "s|'||g") +echo "Opening : ${url}" +ffplay $(youtube-dl -g $url) >/dev/null 2>&1 & +done + + + +while read -p "Enter URL: " w;do +url=$(echo "${w}" |sed "s|'||g"|sed 's/&list.*//') +echo "Opening : ${url}" +ffplay $(youtube-dl -g ${url}) >/dev/null 2>&1 & +done -- 2.44.2