2019-03-08 15:55:46 +00:00
|
|
|
import os
|
2019-03-08 15:48:08 +00:00
|
|
|
import socket
|
2019-03-08 15:35:21 +00:00
|
|
|
from os import environ
|
2019-03-08 15:55:46 +00:00
|
|
|
from pathlib import Path
|
2023-05-24 15:15:36 +00:00
|
|
|
import logging
|
2017-04-29 03:17:22 +00:00
|
|
|
|
2023-05-24 14:07:41 +00:00
|
|
|
from sanic import Sanic, HTTPResponse
|
2019-03-08 15:35:21 +00:00
|
|
|
from sanic.request import Request
|
|
|
|
from sanic.response import text, html, file_stream, redirect
|
2023-05-24 14:07:41 +00:00
|
|
|
from sanic.exceptions import NotFound, MethodNotAllowed
|
2021-06-16 20:32:50 +00:00
|
|
|
from sanic_cors import CORS
|
2023-05-24 14:07:41 +00:00
|
|
|
from sanic_ext import Extend
|
2017-04-29 03:17:22 +00:00
|
|
|
|
2019-03-08 15:35:21 +00:00
|
|
|
from utils import get_j2env, get_sort_icon, get_sort_link, resolve_path, list_dir
|
2017-04-29 03:17:22 +00:00
|
|
|
|
|
|
|
|
2023-05-24 15:05:35 +00:00
|
|
|
DEBUG = Path('.debug').exists()
|
2017-04-29 03:17:22 +00:00
|
|
|
|
2023-05-24 14:07:41 +00:00
|
|
|
app = Sanic('autoindex', strict_slashes=True)
|
|
|
|
Extend(app)
|
2021-06-16 20:32:50 +00:00
|
|
|
cors = CORS(app)
|
2019-03-08 15:35:21 +00:00
|
|
|
app.static('/~static/', '~static/', use_content_range=True, stream_large_files=True)
|
|
|
|
j2env = get_j2env(DEBUG)
|
2017-04-29 03:17:22 +00:00
|
|
|
|
|
|
|
|
2023-05-24 14:07:41 +00:00
|
|
|
@app.get(r'/<path:.*/?>')
|
2019-03-08 15:35:21 +00:00
|
|
|
async def index(request: Request, path=''):
|
2023-05-24 15:15:36 +00:00
|
|
|
logging.warning(path)
|
|
|
|
|
2023-05-24 15:15:03 +00:00
|
|
|
path = path.replace('%20', ' ')
|
2019-03-08 15:35:21 +00:00
|
|
|
domain = request.host
|
|
|
|
query = f'?{request.query_string}' if request.query_string else ''
|
2017-04-29 03:17:22 +00:00
|
|
|
|
|
|
|
try:
|
2019-03-08 15:35:21 +00:00
|
|
|
resolved_path, resolved_query = resolve_path(domain, path)
|
2017-04-29 03:17:22 +00:00
|
|
|
except ValueError:
|
2019-03-08 15:35:21 +00:00
|
|
|
return text('GTFO', 400)
|
|
|
|
|
|
|
|
if resolved_path.is_dir():
|
2017-04-29 03:17:22 +00:00
|
|
|
if path and path[-1] != '/':
|
|
|
|
return redirect(f'/{path}/')
|
|
|
|
|
2019-03-08 15:35:21 +00:00
|
|
|
hidden = request.args.get('hidden') is not None
|
|
|
|
sort = request.args.get('sort', 'name')
|
2017-04-29 03:17:22 +00:00
|
|
|
if sort not in ['name', '-name', 'size', '-size', 'created', '-created']:
|
|
|
|
sort = 'name'
|
|
|
|
|
2019-03-08 15:35:21 +00:00
|
|
|
return html(j2env.get_template('filelist.tpl').render(
|
|
|
|
lst=list_dir(resolved_path, sort, hidden, root=not resolved_query),
|
|
|
|
get_sort_icon=get_sort_icon,
|
|
|
|
get_sort_link=get_sort_link,
|
|
|
|
sort=sort,
|
|
|
|
hidden=hidden,
|
|
|
|
path=resolved_query,
|
|
|
|
query=query,
|
|
|
|
))
|
|
|
|
elif resolved_path.is_file():
|
2023-05-24 14:07:41 +00:00
|
|
|
stream = await file_stream(resolved_path)
|
|
|
|
if request.method == 'HEAD':
|
|
|
|
stream.headers['Content-Length'] = resolved_path.stat().st_size
|
|
|
|
return HTTPResponse(
|
|
|
|
'', status=200, headers=stream.headers, content_type=stream.content_type
|
|
|
|
)
|
|
|
|
return stream
|
2019-03-08 15:35:21 +00:00
|
|
|
|
2022-12-14 12:06:56 +00:00
|
|
|
raise NotFound('Path was not found')
|
2017-04-29 03:17:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2019-03-08 15:35:21 +00:00
|
|
|
if DEBUG:
|
|
|
|
app.run(host='localhost', port=8080, debug=True, auto_reload=True)
|
|
|
|
else:
|
2019-03-08 15:55:46 +00:00
|
|
|
socket_address = Path('/tmp/drop.sock')
|
|
|
|
try:
|
|
|
|
socket_address.unlink()
|
|
|
|
except OSError:
|
|
|
|
if socket_address.exists():
|
|
|
|
raise
|
|
|
|
|
2019-03-08 15:48:08 +00:00
|
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
2019-03-08 16:02:17 +00:00
|
|
|
sock.bind(str(socket_address))
|
2019-03-08 16:06:02 +00:00
|
|
|
socket_address.chmod(0o666)
|
2019-03-08 15:48:08 +00:00
|
|
|
app.run(sock=sock, workers=2)
|