...
 
Commits (2)
......@@ -24,8 +24,24 @@ async def make (path, cwd=".", makefile="makefile"):
# print (f"make {path}: {ret}", file=sys.stderr)
return ret
textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
is_binary_string = lambda bytes: bool(bytes.translate(None, textchars))
def is_binary_file (p):
""" returns none on ioerror """
try:
return not os.path.isdir(p) and is_binary_string(open(p, 'rb').read(1024))
except IOError:
return None
def editable (path):
_, ext = os.path.splitext(path)
ext = ext.lower()[1:]
print (f"editable? ext {ext}", file=sys.stderr)
return ((ext not in ("html", "htm")) and not is_binary_file(path))
# From aiohttp/web_urldispatcher.py
def directory_as_html(filepath, directory, prefix):
def directory_as_html(filepath, directory, prefix, editor_url=None):
# returns directory's index as html
# sanity check
......@@ -44,17 +60,27 @@ def directory_as_html(filepath, directory, prefix):
# rel_path = _file.relative_to(self._directory).as_posix()
# rel_path = os.path.relpath(_file, directory)
# file_url = prefix + '/' + rel_path
file_url = '/' + urlquote(os.path.join(filepath, _file))
fp = os.path.join(filepath, _file)
file_url = '/' + urlquote(fp)
target = None
if editable(fp) and editor_url:
file_url = f"{editor_url}#{file_url}"
target = "editor"
# if file is a directory, add '/' to the end of the name
if os.path.isdir(_file):
file_name = "{}/".format(_file)
else:
file_name = _file
index_list.append(
'<li><a href="{url}">{name}</a></li>'.format(url=file_url,
name=file_name)
)
if target:
link_src = '<li><a href="{url}" target="{target}">{name}</a></li>'.format(
url=file_url,
target="editor",
name=file_name)
else:
link_src = '<li><a href="{url}">{name}</a></li>'.format(
url=file_url,
name=file_name)
index_list.append(link_src)
ul = "<ul>\n{}\n</ul>".format('\n'.join(index_list))
body = "<body>\n{}\n{}\n</body>".format(h1, ul)
......@@ -73,7 +99,7 @@ async def route_get (request):
await make(path, makefile=request.app['makefile'])
if os.path.exists(path):
if os.path.isdir(path):
return web.Response(text=directory_as_html(path, '', ''), content_type="text/html")
return web.Response(text=directory_as_html(path, '', '', editor_url=request.app['editor']), content_type="text/html")
else:
return web.FileResponse(path, chunk_size=256*1024)
else:
......@@ -99,6 +125,7 @@ async def route_post (request):
def main ():
ap = argparse.ArgumentParser("make & serve")
ap.add_argument("--makefile", default="makefile")
ap.add_argument("--editor", default=None)
args = ap.parse_args()
if sys.platform == 'win32':
# Folowing: https://docs.python.org/3/library/asyncio-subprocess.html
......@@ -108,6 +135,7 @@ def main ():
asyncio.set_event_loop(loop)
app = web.Application()
app['makefile'] = args.makefile
app['editor'] = args.editor
app.add_routes([web.get('/{make:.*}', route_get)])
app.add_routes([web.post('/{make:.*}', route_post)])
web.run_app(app)
......