diff --git a/pyproject.toml b/pyproject.toml index dbdabe1..b6a67e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ ] [tool.setuptools.package-data] -md2html = ['static/*.html', 'static/*.css', 'static/*.js'] +md2html = ['static/*'] [project.urls] "Homepage" = "https://github.com/woggioni/md2html" diff --git a/src/md2html/md2html.py b/src/md2html/md2html.py index 9cf95a1..be8507a 100644 --- a/src/md2html/md2html.py +++ b/src/md2html/md2html.py @@ -1,20 +1,25 @@ import sys from os.path import dirname, join, relpath from time import time -from typing import Optional +from typing import Optional, TYPE_CHECKING import markdown +if TYPE_CHECKING: + from _typeshed import StrOrBytesPath + STATIC_RESOURCES: set[str] = { '/github-markdown.css', '/custom.css', '/hot-reload.js', '/pygment.css', + '/markdown.svg' } STATIC_CACHE: dict[str, tuple[str, float]] = {} MARDOWN_EXTENSIONS = ['extra', 'smarty', 'tables', 'codehilite'] + def load_from_cache(path) -> tuple[str, float]: global STATIC_CACHE if path not in STATIC_CACHE: @@ -24,7 +29,8 @@ def load_from_cache(path) -> tuple[str, float]: def compile_html(url_path, - mdfile=None, + mdfile: 'StrOrBytesPath', + prefix: Optional['StrOrBytesPath'] = None, extensions: Optional[list[str]] = None, raw: bool = False) -> str: with mdfile and open(mdfile, 'r') or sys.stdin as instream: @@ -33,9 +39,9 @@ def compile_html(url_path, doc = html else: parent = dirname(url_path) - prefix = relpath('/', start=parent) + prefix = prefix or relpath('/', start=parent) script = f'' - css = '' + css = f'' for css_file in ('github-markdown.css', 'pygment.css', 'custom.css'): css += f' ' doc = load_from_cache('/template.html')[0].format(content=html, script=script, css=css) diff --git a/src/md2html/server.py b/src/md2html/server.py index c711a7b..57b4cd6 100644 --- a/src/md2html/server.py +++ b/src/md2html/server.py @@ -1,6 +1,6 @@ import logging from os import getcwd, listdir -from os.path import exists, splitext, isfile, join, relpath, isdir, basename, getmtime, dirname +from os.path import exists, splitext, isfile, join, relpath, isdir, basename, getmtime, dirname, normpath from mimetypes import init as mimeinit, guess_type import hashlib from .md2html import compile_html, load_from_cache, STATIC_RESOURCES, MARDOWN_EXTENSIONS @@ -33,17 +33,20 @@ def is_dotfile(filepath): class Server: - def __init__(self, root_dir: 'StrOrBytesPath' = getcwd()): + def __init__(self, root_dir: 'StrOrBytesPath' = getcwd(), prefix: Optional['StrOrBytesPath'] = None): self.root_dir = root_dir self.cache = dict['StrOrBytesPath', tuple[str, float]]() self.file_watcher = FileWatcher(cwd) self.logger = logging.getLogger(Server.__name__) + self.prefix = prefix and normpath(f'{prefix.decode()}') def handle_request(self, method: str, url_path: str, etag: Optional[str], query_string: Optional[str], start_response): if method != 'GET': start_response('405', []) return [] - path: 'StrOrBytesPath' = join(self.root_dir, relpath(url_path, '/')) + relative_path = relpath(url_path, start=self.prefix or '/') + url_path: 'StrOrBytesPath' = normpath(join('/', relative_path)) + path: 'StrOrBytesPath' = join(self.root_dir, relative_path) if url_path in STATIC_RESOURCES: content, mtime = load_from_cache(url_path) content = content.encode() @@ -186,14 +189,15 @@ class Server: etag = Server.parse_etag(etag_header) return etag, digest - @staticmethod - def render_markdown(url_path: 'StrOrBytesPath', + def render_markdown(self, + url_path: 'StrOrBytesPath', path: str, raw: bool, digest: str, start_response) -> list[bytes]: body = compile_html(url_path, path, + self.prefix, MARDOWN_EXTENSIONS, raw=raw).encode() start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8'), @@ -214,10 +218,11 @@ class Server: start_response('404 NOT_FOUND', []) return [] - @staticmethod - def directory_listing(path_info, path) -> str: + def directory_listing(self, path_info, path) -> str: + icon_path = join(self.prefix or '', 'markdown.svg') title = "Directory listing for %s" % path_info result = "" + result += f'' result += "" result += "" + title + "" result += "

" + title + "


" diff --git a/src/md2html/static/markdown.svg b/src/md2html/static/markdown.svg new file mode 100644 index 0000000..e13150b --- /dev/null +++ b/src/md2html/static/markdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/md2html/uwsgi_handler.py b/src/md2html/uwsgi_handler.py index e9380f8..3c6602a 100644 --- a/src/md2html/uwsgi_handler.py +++ b/src/md2html/uwsgi_handler.py @@ -1,6 +1,6 @@ import logging from .server import Server -from uwsgi import log +from uwsgi import log, opt class UwsgiHandler(logging.Handler): def emit(self, record: logging.LogRecord) -> None: @@ -13,7 +13,7 @@ logging.basicConfig( handlers=[UwsgiHandler()] ) -server = Server() +server = Server(prefix=opt.get('prefix', None)) def application(env, start_response): return server.handle_request(