From b6cf2d3089e0370cd2c63c99d3d8fb2a598fd0fe Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 1 May 2024 20:24:18 +0000 Subject: [PATCH] `--html-head` can take a filepath and/or jinja2 --- README.md | 2 +- copyparty/__main__.py | 2 +- copyparty/cfg.py | 4 ++-- copyparty/httpcli.py | 41 ++++++++++++++++++++++++++++++++++++++--- docs/rice/README.md | 8 ++++++++ 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7635e4d3..9fd800bc 100644 --- a/README.md +++ b/README.md @@ -1067,7 +1067,7 @@ tweaking the ui * to sort in music order (album, track, artist, title) with filename as fallback, you could `--sort tags/Cirle,tags/.tn,tags/Artist,tags/Title,href` * to sort by upload date, first enable showing the upload date in the listing with `-e2d -mte +.up_at` and then `--sort tags/.up_at` -see [./docs/rice](./docs/rice) for more +see [./docs/rice](./docs/rice) for more, including how to add stuff (css/``/...) to the html `` tag ## file indexing diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 940d77ce..fb71764c 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1269,7 +1269,7 @@ def add_ui(ap, retry): ap2.add_argument("--mpmc", metavar="URL", type=u, default="", help="change the mediaplayer-toggle mouse cursor; URL to a folder with {2..5}.png inside (or disable with [\033[32m.\033[0m])") ap2.add_argument("--js-browser", metavar="L", type=u, help="URL to additional JS to include") ap2.add_argument("--css-browser", metavar="L", type=u, help="URL to additional CSS to include") - ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the of all HTML pages") + ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the of all HTML pages; can be @PATH to send the contents of a file at PATH, and/or begin with % to render as jinja2 template (volflag=html_head)") ap2.add_argument("--ih", action="store_true", help="if a folder contains index.html, show that instead of the directory listing by default (can be changed in the client settings UI, or add ?v to URL for override)") ap2.add_argument("--textfiles", metavar="CSV", type=u, default="txt,nfo,diz,cue,readme", help="file extensions to present as plaintext") ap2.add_argument("--txt-max", metavar="KiB", type=int, default=64, help="max size of embedded textfiles on ?doc= (anything bigger will be lazy-loaded by JS)") diff --git a/copyparty/cfg.py b/copyparty/cfg.py index b2cffcb5..e2ce7d00 100644 --- a/copyparty/cfg.py +++ b/copyparty/cfg.py @@ -61,6 +61,7 @@ def vf_vmap() -> dict[str, str]: } for k in ( "dbd", + "html_head", "lg_sbf", "md_sbf", "nrand", @@ -81,7 +82,6 @@ def vf_cmap() -> dict[str, str]: for k in ( "exp_lg", "exp_md", - "html_head", "mte", "mth", "mtp", @@ -201,7 +201,7 @@ flagcats = { "grid": "show grid/thumbnails by default", "sort": "default sort order", "unlist": "dont list files matching REGEX", - "html_head=TXT": "includes TXT in the ", + "html_head=TXT": "includes TXT in the , or @PATH for file at PATH", "robots": "allows indexing by search engines (default)", "norobots": "kindly asks search engines to leave", "no_sb_md": "disable js sandbox for markdown files", diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 1367e6b5..da61a351 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -217,6 +217,12 @@ class HttpCli(object): ka["favico"] = self.args.favico ka["s_name"] = self.args.bname ka["s_doctitle"] = self.args.doctitle + + zso = self.vn.flags.get("html_head") + if zso: + ka["this"] = self + self._build_html_head(zso, ka) + ka["html_head"] = self.html_head return tpl.render(**ka) # type: ignore @@ -718,6 +724,31 @@ class HttpCli(object): or ("; Trident/" in self.ua and not k304) ) + def _build_html_head(self, maybe_html: Any, kv: dict[str, Any]) -> bool: + html = str(maybe_html) + is_jinja = html[:2] in "%@%" + if is_jinja: + html = html.replace("%", "", 1) + + if html.startswith("@"): + with open(html[1:], "rb") as f: + html = f.read().decode("utf-8") + + if html.startswith("%"): + html = html[1:] + is_jinja = True + + if is_jinja: + print("applying jinja") + with self.conn.hsrv.mutex: + if html not in self.conn.hsrv.j2: + j2env = jinja2.Environment() + tpl = j2env.from_string(html) + self.conn.hsrv.j2[html] = tpl + html = self.conn.hsrv.j2[html].render(**kv) + + self.html_head += html + "\n" + def send_headers( self, length: Optional[int], @@ -3484,7 +3515,6 @@ class HttpCli(object): targs = { "r": self.args.SR if self.is_vproxied else "", "ts": self.conn.hsrv.cachebuster(), - "html_head": self.html_head, "edit": "edit" in self.uparam, "title": html_escape(self.vpath, crlf=True), "lastmod": int(ts_md * 1000), @@ -3495,6 +3525,13 @@ class HttpCli(object): "md": boundary, "arg_base": arg_base, } + + zfv = self.vn.flags.get("html_head") + if zfv: + targs["this"] = self + self._build_html_head(zfv, targs) + + targs["html_head"] = self.html_head zs = template.render(**targs).encode("utf-8", "replace") html = zs.split(boundary.encode("utf-8")) if len(html) != 2: @@ -3610,8 +3647,6 @@ class HttpCli(object): self.reply(zb, mime="text/plain; charset=utf-8") return True - self.html_head += self.vn.flags.get("html_head", "") - html = self.j2s( "splash", this=self, diff --git a/docs/rice/README.md b/docs/rice/README.md index 6c5a16bd..fd373556 100644 --- a/docs/rice/README.md +++ b/docs/rice/README.md @@ -47,3 +47,11 @@ and if you want to have a monospace font in the fancy markdown editor, do this: NB: `