Skip to content

Commit

Permalink
--html-head can take a filepath and/or jinja2
Browse files Browse the repository at this point in the history
  • Loading branch information
9001 committed May 1, 2024
1 parent e8db3dd commit b6cf2d3
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/`<meta>`/...) to the html `<head>` tag
## file indexing
Expand Down
2 changes: 1 addition & 1 deletion copyparty/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 <head> of all HTML pages")
ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the <head> 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)")
Expand Down
4 changes: 2 additions & 2 deletions copyparty/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def vf_vmap() -> dict[str, str]:
}
for k in (
"dbd",
"html_head",
"lg_sbf",
"md_sbf",
"nrand",
Expand All @@ -81,7 +82,6 @@ def vf_cmap() -> dict[str, str]:
for k in (
"exp_lg",
"exp_md",
"html_head",
"mte",
"mth",
"mtp",
Expand Down Expand Up @@ -201,7 +201,7 @@ def vf_cmap() -> dict[str, str]:
"grid": "show grid/thumbnails by default",
"sort": "default sort order",
"unlist": "dont list files matching REGEX",
"html_head=TXT": "includes TXT in the <head>",
"html_head=TXT": "includes TXT in the <head>, 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",
Expand Down
41 changes: 38 additions & 3 deletions copyparty/httpcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ def j2s(self, name: str, **ka: Any) -> str:
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

Expand Down Expand Up @@ -718,6 +724,31 @@ def k304(self) -> bool:
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],
Expand Down Expand Up @@ -3484,7 +3515,6 @@ def tx_md(self, vn: VFS, fs_path: str) -> bool:
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),
Expand All @@ -3495,6 +3525,13 @@ def tx_md(self, vn: VFS, fs_path: str) -> bool:
"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:
Expand Down Expand Up @@ -3610,8 +3647,6 @@ def tx_mounts(self) -> bool:
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,
Expand Down
8 changes: 8 additions & 0 deletions docs/rice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ and if you want to have a monospace font in the fancy markdown editor, do this:

NB: `<textarea id="mt">` and `<div id="mtr">` in the regular markdown editor must have the same font; none of the suggestions above will cause any issues but keep it in mind if you're getting creative


# `<head>`

to add stuff to the html `<head>`, for example a css `<link>` or `<meta>` tags, use either the global-option `--html-head` or the volflag `html_head`

if you give it the value `@ASDF` it will try to open a file named ASDF and send the text within

if the value starts with `%` it will assume a jinja2 template and expand it; the template has access to the `HttpCli` object through a property named `this` as well as everything in `j2a` and the stuff added by `self.j2s`; see [browser.html](https://github.com/9001/copyparty/blob/hovudstraum/copyparty/web/browser.html) for inspiration or look under the hood in [httpcli.py](https://github.com/9001/copyparty/blob/hovudstraum/copyparty/httpcli.py)

0 comments on commit b6cf2d3

Please sign in to comment.