diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..9bdcf1e --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,18 @@ +FROM alpine:latest +MAINTAINER Oggioni Walter +#ADD ../dist/md2html-0.2-py3-none-any.whl / +#COPY md2html-*.whl / +ADD md2html-*.whl / +RUN apk update +RUN apk add python3 uwsgi uwsgi-python3 +RUN pip3 install /md2html-*.whl && rm /*.whl +RUN mkdir /srv/http +VOLUME /srv/http +WORKDIR /srv/http +ENTRYPOINT ["uwsgi"] +EXPOSE 1180/tcp +EXPOSE 1180/udp +USER nobody +CMD ["--plugin", "/usr/lib/uwsgi/python_plugin.so", "-s", ":1180", "-w", "md2html.uwsgi"] +#RUN useradd luser -s /bin/bash -m -G users + diff --git a/md2html/__init__.py b/md2html/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/md2html/uwsgi.py b/md2html/uwsgi.py new file mode 100644 index 0000000..6b80144 --- /dev/null +++ b/md2html/uwsgi.py @@ -0,0 +1,87 @@ +import logging +from os import getcwd, listdir +from os.path import exists, splitext, isfile, join, relpath, isdir + +import hashlib +from .md2html import compile_html + +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +cwd = getcwd() + +def is_markdown(filepath): + _, ext = splitext(filepath) + return ext == ".md" + +cache = dict() + +def file_hash(filepath, bufsize=4096): + if bufsize <= 0: + raise ValueError("Buffer size must be greater than 0") + md5 = hashlib.md5() + with open(filepath, 'rb') as f: + while True: + buf = f.read(bufsize) + if len(buf) == 0: + break + md5.update(buf) + return md5.digest() + +def application(env, start_response): + path = join(cwd, relpath(env['PATH_INFO'], '/')) + + if exists(path): + if isfile(path) and is_markdown(path): + if path not in cache: + digest = file_hash(path).hex() + cache[path] = digest + else: + digest = cache[path] + etag = env.get('HTTP_IF_NONE_MATCH') + if etag and etag[1:-1] == digest: + start_response('301 Not Modified', [ + ('Content-Type', 'text/html'), + ('Content-Length', str(0)), + ('Cache-Control', 'no-cache, must-revalidate, max-age=86400'), + ('Connection', 'keep-alive') + ]) + return [] + else: + body = compile_html(path, ['extra', 'smarty', 'tables']).encode() + start_response('200 OK', [('Content-Type', 'text/html'), + ('Content-Length', str(len(body))), + ('Etag', '"%s"' % digest), + ('Cache-Control', 'no-cache, must-revalidate, max-age=86400'), + ('Connection', 'keep-alive'), + ]) + return [body] + elif isdir(path): + body = directory_listing(env['PATH_INFO'], path).encode() + start_response('200 OK', [ + ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ('Connection', 'keep-alive'), + ]) + return [body] + start_response('404 NOT_FOUND', [('Content-Length', str(0)), ('Connection', 'keep-alive')]) + return [] + + +def directory_listing(path_info, path): + title = "Directory listing for %s" % path_info + result = "" + result += "" + result += "" + title + "" + result += "

" + title + "


" + result += "