lots of changes

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.
This commit is contained in:
Christian Lawson-Perfect 2025-02-07 07:02:35 +00:00
parent 3d5c0c6c73
commit 500eb38774
13 changed files with 1474 additions and 396 deletions

72
thinks/make.py Normal file
View file

@ -0,0 +1,72 @@
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"}