Added a creation_time field to thinks - using the modified time on the filesystem wasn't reliable. Styled the login page. The index shows the most recent thinks at the top. Allow authentication by an Authorization header, with a token specified in settings.py. Lots of improvements to the editor, including showing the log, and a form to install Elm packages when editing .elm files. The Makefile for a project is automatically run each time a file is saved.
72 lines
2 KiB
Python
72 lines
2 KiB
Python
from datetime import datetime
|
|
from filelock import FileLock, Timeout
|
|
import subprocess
|
|
import yaml
|
|
|
|
class ThingMaker():
|
|
|
|
gap = 2
|
|
|
|
extensions = None
|
|
|
|
config = {
|
|
'path': '.',
|
|
'default_make': [],
|
|
'extensions': ['.js'],
|
|
}
|
|
|
|
def __init__(self, think):
|
|
self.think = think
|
|
self.load_config()
|
|
|
|
|
|
def load_config(self,):
|
|
config_path = self.think.root / '.watchmakerc'
|
|
|
|
if config_path.exists():
|
|
with open(config_path) as f:
|
|
self.config.update(yaml.load(f.read(),Loader=yaml.SafeLoader))
|
|
|
|
self.extensions = self.config.get('extensions')
|
|
|
|
|
|
def make(self, file_changed):
|
|
if file_changed.is_dir():
|
|
return {"error": f"{file_changed} is directory"}
|
|
|
|
root = self.think.root
|
|
|
|
t = datetime.now()
|
|
|
|
src_path = (root / file_changed).resolve()
|
|
|
|
if not src_path.is_relative_to(root.resolve()):
|
|
return {"error": f"{src_path} is not relative to root {root}"}
|
|
|
|
if src_path.name == '.watchmakerc' or self.extensions is None or src_path.suffix in self.extensions:
|
|
lock_path = str(root / '.make.lock')
|
|
lock = FileLock(lock_path, timeout=5)
|
|
|
|
try:
|
|
with lock:
|
|
return self.run(src_path)
|
|
except Timeout:
|
|
return {"error": "Timed out"}
|
|
|
|
|
|
def run(self, p):
|
|
root = self.think.root
|
|
if (root / 'Makefile').exists():
|
|
command = ['make'] + self.config.get('default_make', [])
|
|
res = subprocess.run(command, cwd=root, capture_output=True, encoding='utf-8')
|
|
with open(root / '.make.log', 'w') as f:
|
|
f.write(f"{datetime.now()}\n")
|
|
f.write(res.stdout)
|
|
f.write(res.stderr)
|
|
|
|
return {
|
|
'stdout': res.stdout,
|
|
'stderr': res.stderr,
|
|
}
|
|
else:
|
|
return {"error": "No make"}
|