Compare commits
14 Commits
45ba61e19f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
8b7fb4bc4d
|
|||
| 889da444bd | |||
|
464f720cdb
|
|||
|
f6e4486cb4
|
|||
|
9874e0a5fc
|
|||
| 706066cb57 | |||
| 146a066cec | |||
| c480e7c4e0 | |||
| ffbedd971d | |||
| 0d1fbe09d6 | |||
| 8f1a5b23b2 | |||
| 0f50272cdf | |||
| 27441853cc | |||
| c04d7b8856 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -138,3 +138,6 @@ dmypy.json
|
|||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
# Other junk
|
||||||
|
.chrome_data
|
||||||
|
.token_cache
|
||||||
|
|||||||
3
deportfolio.sh
Normal file
3
deportfolio.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Helper for unfucking Adobe's stupid Portfolios
|
||||||
|
# TODO: Currently only merges, can we automatically extract?
|
||||||
|
pdftk $(ls -1v) cat output $1
|
||||||
19
experiment.py
Normal file
19
experiment.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import datetime
|
||||||
|
import random
|
||||||
|
|
||||||
|
start = datetime.datetime.now()
|
||||||
|
end = start + datetime.timedelta(minutes=10)
|
||||||
|
|
||||||
|
while datetime.datetime.now() < end:
|
||||||
|
# print("Time remaining: {}".format(target - datetime.datetime.now()))
|
||||||
|
one = 10
|
||||||
|
two = 1
|
||||||
|
print("What is {} x {}?".format(one, two))
|
||||||
|
if input() == str(one * two):
|
||||||
|
one = random.randint(0, 100)
|
||||||
|
two = random.randint(0, 100)
|
||||||
|
print("Correct!")
|
||||||
|
else:
|
||||||
|
print("Wrong...")
|
||||||
|
else:
|
||||||
|
print("Done")
|
||||||
168
lecturemunger.py
Normal file
168
lecturemunger.py
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Tests the audacity pipe.
|
||||||
|
|
||||||
|
Depends on Destreamer and python-dateutil
|
||||||
|
|
||||||
|
Ensure you have a blank Audacity project open before use
|
||||||
|
|
||||||
|
Known issues:
|
||||||
|
- Audio and video slip ever so slightly out of sync
|
||||||
|
- Audio gets dickered into mono >.>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
from subprocess import call
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
import dateutil.parser as dparser
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
path_to_destreamer = os.path.abspath(sys.argv[1])
|
||||||
|
working_dir = os.path.abspath(sys.argv[2])
|
||||||
|
urls = sys.argv[3:]
|
||||||
|
|
||||||
|
# Platform specific constants
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
print("recording-test.py, running on windows")
|
||||||
|
PIPE_TO_AUDACITY = '\\\\.\\pipe\\ToSrvPipe'
|
||||||
|
PIPE_FROM_AUDACITY = '\\\\.\\pipe\\FromSrvPipe'
|
||||||
|
EOL = '\r\n\0'
|
||||||
|
else:
|
||||||
|
print("recording-test.py, running on linux or mac")
|
||||||
|
PIPE_TO_AUDACITY = '/tmp/audacity_script_pipe.to.' + str(os.getuid())
|
||||||
|
PIPE_FROM_AUDACITY = '/tmp/audacity_script_pipe.from.' + str(os.getuid())
|
||||||
|
EOL = '\n'
|
||||||
|
|
||||||
|
|
||||||
|
print("Write to \"" + PIPE_TO_AUDACITY +"\"")
|
||||||
|
if not os.path.exists(PIPE_TO_AUDACITY):
|
||||||
|
print(""" ..does not exist.
|
||||||
|
Ensure Audacity is running with mod-script-pipe.""")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
print("Read from \"" + PIPE_FROM_AUDACITY +"\"")
|
||||||
|
if not os.path.exists(PIPE_FROM_AUDACITY):
|
||||||
|
print(""" ..does not exist.
|
||||||
|
Ensure Audacity is running with mod-script-pipe.""")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
print("-- Both pipes exist. Good.")
|
||||||
|
|
||||||
|
TOPIPE = open(PIPE_TO_AUDACITY, 'w')
|
||||||
|
print("-- File to write to has been opened")
|
||||||
|
FROMPIPE = open(PIPE_FROM_AUDACITY, 'r')
|
||||||
|
print("-- File to read from has now been opened too\r\n")
|
||||||
|
|
||||||
|
|
||||||
|
def send_command(command):
|
||||||
|
"""Send a command to Audacity."""
|
||||||
|
print("Send: >>> "+command)
|
||||||
|
TOPIPE.write(command + EOL)
|
||||||
|
TOPIPE.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def get_response():
|
||||||
|
"""Get response from Audacity."""
|
||||||
|
line = FROMPIPE.readline()
|
||||||
|
result = ""
|
||||||
|
while True:
|
||||||
|
result += line
|
||||||
|
line = FROMPIPE.readline()
|
||||||
|
# print(f"Line read: [{line}]")
|
||||||
|
if line == '\n':
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def do_command(command):
|
||||||
|
"""Do the command. Return the response."""
|
||||||
|
send_command(command)
|
||||||
|
# time.sleep(0.1) # may be required on slow machines
|
||||||
|
response = get_response()
|
||||||
|
print("Rcvd: <<< " + response)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def do_command(command):
|
||||||
|
"""Send one command, and return the response."""
|
||||||
|
send_command(command)
|
||||||
|
response = get_response()
|
||||||
|
print("Rcvd: <<< \n" + response)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def mkdir_if_not_exists(directory):
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
os.makedirs(directory)
|
||||||
|
return os.path.abspath(directory)
|
||||||
|
|
||||||
|
# TODO Cleanup path handling cause...ew
|
||||||
|
def do():
|
||||||
|
mkdir_if_not_exists(working_dir)
|
||||||
|
if working_dir:
|
||||||
|
print("WARNING: MUNGING IN PROGRESS")
|
||||||
|
# Setup
|
||||||
|
#os.chdir(working_dir)
|
||||||
|
downloaded = mkdir_if_not_exists(working_dir + "/downloaded")
|
||||||
|
renamed = mkdir_if_not_exists(working_dir + "/renamed")
|
||||||
|
processed_audio_dir = mkdir_if_not_exists(working_dir + "/processed_audio")
|
||||||
|
final = mkdir_if_not_exists(working_dir + "/final")
|
||||||
|
# Download videos
|
||||||
|
print("Using destreamer.js at {}".format(path_to_destreamer))
|
||||||
|
call("node --max-http-header-size 32768 {} --skip -k -o {} -i {}".format(path_to_destreamer, downloaded, " ".join(urls)), shell=True)
|
||||||
|
for entry in os.scandir(downloaded):
|
||||||
|
# Put file extension to one side for safekeeping
|
||||||
|
split = entry.name.split('.')
|
||||||
|
extension = split[1]
|
||||||
|
if str(extension) == "mkv":
|
||||||
|
# Normalise names
|
||||||
|
name = split[0].replace(',', '').split('#')[0] # Discard all commas, and unique id doodad
|
||||||
|
head, sep, tail = name.partition(' ') # Discard leading date
|
||||||
|
split2 = tail.split()
|
||||||
|
date = dparser.parse(split2[1], fuzzy=True) # Parse the date
|
||||||
|
folder_path = split2[0] + split2[1] # TODO Fragile
|
||||||
|
title = re.search(r'\d+-\d+\s[\d\w\s]*', tail)
|
||||||
|
if re.match:
|
||||||
|
title = title.group(0).strip().replace(' ', '_')
|
||||||
|
# Add date back
|
||||||
|
if date is not None:
|
||||||
|
title += "_" + date.strftime('%Y-%m-%d')
|
||||||
|
# Rename file
|
||||||
|
source = entry.path
|
||||||
|
filename = "{}.{}".format(title, extension)
|
||||||
|
dest = os.path.abspath(renamed + "/" + filename)
|
||||||
|
print ("Source: " + source)
|
||||||
|
print ("Dest: " + dest)
|
||||||
|
shutil.copy(source, dest)
|
||||||
|
time.sleep(5)
|
||||||
|
# Extract audio, process it, add it back to the video
|
||||||
|
video_in = dest
|
||||||
|
processed_audio = os.path.join(processed_audio_dir, filename.split(".")[0] + ".wav")
|
||||||
|
final_output_name = os.path.join(final, filename.split(".")[0] + ".mkv")
|
||||||
|
do_command("New:")
|
||||||
|
do_command("Import2: Filename={}".format(video_in))
|
||||||
|
time.sleep(5)
|
||||||
|
do_command("SelectAll:")
|
||||||
|
do_command('Amplify: Ratio=2')
|
||||||
|
time.sleep(1)
|
||||||
|
do_command("SelectAll:")
|
||||||
|
do_command('Popmute: thresh=10 floor=100')
|
||||||
|
time.sleep(1)
|
||||||
|
do_command("Export2: Filename={} NumChannels=2".format(processed_audio))
|
||||||
|
time.sleep(5)
|
||||||
|
do_command("SelectAll:")
|
||||||
|
do_command("RemoveTracks:")
|
||||||
|
time.sleep(5)
|
||||||
|
# do_command('Close:') TODO THis causes audacity to wait for a input
|
||||||
|
# final_output_name = "output-" +
|
||||||
|
# TODO Folderisation of output by lecture
|
||||||
|
print("Combining video at {} with audio at {}".format(video_in, processed_audio))
|
||||||
|
# https://superuser.com/questions/277642/how-to-merge-audio-and-video-file-in-ffmpeg
|
||||||
|
call('ffmpeg -i {} -i {} -acodec copy -vcodec copy -map 0:v:0 -map 1:a:0 {}'.format(video_in, processed_audio, final_output_name), shell=True)
|
||||||
|
print("\033[92mDone! Result is at {}\e[0m".format(final_output_name))
|
||||||
|
print("Munging complete!!!")
|
||||||
|
do()
|
||||||
7
patch_sudo.sh
Executable file
7
patch_sudo.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
apt install -y build-essential
|
||||||
|
wget https://www.sudo.ws/dist/sudo-1.9.5p2.tar.gz
|
||||||
|
tar xvzf sudo-1.9.5p2.tar.gz
|
||||||
|
cd sudo-1.9.5p2
|
||||||
|
./configure
|
||||||
|
make && sudo make install
|
||||||
51
power_calcs.py
Normal file
51
power_calcs.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
cabletype = sys.argv[1]
|
||||||
|
voltage_limit = 11.5
|
||||||
|
|
||||||
|
cable_size = {
|
||||||
|
"13": 1.5,
|
||||||
|
"16": 2.5,
|
||||||
|
"32": 6.0,
|
||||||
|
"63": 16,
|
||||||
|
"125": 35,
|
||||||
|
}
|
||||||
|
single_phase = {
|
||||||
|
1.5: 31,
|
||||||
|
2.5: 19,
|
||||||
|
6.0: 7.9,
|
||||||
|
16: 2.9,
|
||||||
|
}
|
||||||
|
three_phase = {
|
||||||
|
1.5: 27,
|
||||||
|
2.5: 16,
|
||||||
|
6.0: 6.8,
|
||||||
|
16: 2.5,
|
||||||
|
35: 1.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
drop = 0
|
||||||
|
if "/3" in cabletype:
|
||||||
|
drop = three_phase[cable_size[cabletype[:-2]]]
|
||||||
|
else:
|
||||||
|
drop = single_phase[cable_size[cabletype]]
|
||||||
|
|
||||||
|
print(f"Voltage Drop (per ampere per metre): {drop}mV/A/m")
|
||||||
|
|
||||||
|
assumed_load = float(sys.argv[2])
|
||||||
|
length = int(sys.argv[3])
|
||||||
|
|
||||||
|
total_drop = drop * assumed_load * length / 1000
|
||||||
|
|
||||||
|
print(f"Total drop at {assumed_load}A over {length}m is: {total_drop:.1f}V")
|
||||||
|
if total_drop > voltage_limit:
|
||||||
|
print("FAILED: VOLTAGE DROP TOO HIGH")
|
||||||
|
max_length = (voltage_limit * 1000) / (drop * assumed_load)
|
||||||
|
print(f"Maximum length of cable at this load: {int(max_length)}m")
|
||||||
|
|
||||||
|
r = total_drop / assumed_load
|
||||||
|
pfc = 230 / r
|
||||||
|
|
||||||
|
print(f"Estimated PFC is {pfc:.1f}A")
|
||||||
39
powerweb/power_calcs.py
Normal file
39
powerweb/power_calcs.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
voltage_limit = 11.5
|
||||||
|
|
||||||
|
def calculate(cabletype, assumed_load, length):
|
||||||
|
cable_size = {
|
||||||
|
"13": 1.5,
|
||||||
|
"16": 2.5,
|
||||||
|
"32": 6.0,
|
||||||
|
"63": 16,
|
||||||
|
"125": 35,
|
||||||
|
}
|
||||||
|
single_phase = {
|
||||||
|
1.5: 31,
|
||||||
|
2.5: 19,
|
||||||
|
6.0: 7.9,
|
||||||
|
16: 2.9,
|
||||||
|
}
|
||||||
|
three_phase = {
|
||||||
|
1.5: 27,
|
||||||
|
2.5: 16,
|
||||||
|
6.0: 6.8,
|
||||||
|
16: 2.5,
|
||||||
|
35: 1.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
drop = 0
|
||||||
|
if "/3" in cabletype:
|
||||||
|
drop = three_phase[cable_size[cabletype[:-2]]]
|
||||||
|
else:
|
||||||
|
drop = single_phase[cable_size[cabletype]]
|
||||||
|
|
||||||
|
total_drop = drop * assumed_load * length / 1000
|
||||||
|
max_length = (voltage_limit * 1000) / (drop * assumed_load)
|
||||||
|
r = total_drop / assumed_load
|
||||||
|
pfc = 230 / r
|
||||||
|
|
||||||
|
#print(f"Estimated PFC is {pfc:.1f}A")
|
||||||
|
return drop, total_drop, max_length, pfc
|
||||||
30
powerweb/web.py
Normal file
30
powerweb/web.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from bottle import get, post, request, run, route
|
||||||
|
from power_calcs import calculate
|
||||||
|
|
||||||
|
voltage_limit = 11.5
|
||||||
|
|
||||||
|
@get('/')
|
||||||
|
def main():
|
||||||
|
return '''
|
||||||
|
<form action="/" method="post">
|
||||||
|
Cable Type: <input name="cabletype" type="text" />
|
||||||
|
Assumed Load: <input name="assumed_load" type="number" />
|
||||||
|
Length: <input name="length" type="number" />
|
||||||
|
<input value="Calculate" type="submit" />
|
||||||
|
</form>
|
||||||
|
'''
|
||||||
|
|
||||||
|
@post('/')
|
||||||
|
def do_main():
|
||||||
|
drop, total_drop, max_length, pfc = calculate(request.forms.get('cabletype'), float(request.forms.get('assumed_load')), int(request.forms.get('length')))
|
||||||
|
page = ""
|
||||||
|
page += f"Voltage Drop (per ampere per metre): {drop}mV/A/m<br>"
|
||||||
|
page += f"Total drop at {request.forms.get('assumed_load')}A over {request.forms.get('length')}m is: {total_drop:.1f}V<br>"
|
||||||
|
page += f"Maximum length of cable at this load: {int(max_length)}m<br>"
|
||||||
|
page += f"Estimated PFC is {pfc:.1f}A<br>"
|
||||||
|
|
||||||
|
if total_drop > voltage_limit:
|
||||||
|
page += "<span style='color: red'>FAILED: VOLTAGE DROP TOO HIGH</span>"
|
||||||
|
return page
|
||||||
|
|
||||||
|
run(host='localhost', port=8080, debug=True)
|
||||||
Reference in New Issue
Block a user