diff --git a/README.md b/README.md index 9adf38db..46cfa25f 100644 --- a/README.md +++ b/README.md @@ -1082,9 +1082,9 @@ note that this disables hotlinking because the opengraph spec demands it; to sne you can also hotlink files regardless by appending `?raw` to the url -if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object) +NOTE: because discord (and maybe others) strip query args such as `?raw` in opengraph tags, any links which require a filekey or dirkey will not work -because discord (and maybe others) strip query args such as `?raw`, opengraph is incompatible with filekeys and dirkeys +if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object) ## file indexing diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 57da50f9..c83cd482 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1264,9 +1264,14 @@ def add_og(ap): ap2.add_argument("--og-tpl", metavar="PATH", type=u, default="", help="do not return the regular copyparty html, but instead load the jinja2 template at \033[33mPATH\033[0m (if path contains 'EXT' then EXT will be replaced with the requested file's extension) (volflag=og_tpl)") ap2.add_argument("--og-no-head", action="store_true", help="do not automatically add OG entries into
(useful if you're doing this yourself in a template or such) (volflag=og_no_head)") ap2.add_argument("--og-th", metavar="FMT", type=u, default="jf3", help="thumbnail format; j=jpeg, jf=jpeg-uncropped, jf3=jpeg-uncropped-large, w=webm, ... (volflag=og_th)") - ap2.add_argument("--og-title", metavar="TXT", type=u, default="", help="fallback title if there is nothing in the \033[33m-e2t\033[0m database (volflag=og_site)") + ap2.add_argument("--og-title", metavar="TXT", type=u, default="", help="fallback title if there is nothing in the \033[33m-e2t\033[0m database (volflag=og_title)") + ap2.add_argument("--og-title-a", metavar="T", type=u, default="🎵 {{ artist }} - {{ title }}", help="audio title format; takes any metadata key (volflag=og_title_a)") + ap2.add_argument("--og-title-v", metavar="T", type=u, default="{{ title }}", help="video title format; takes any metadata key (volflag=og_title_v)") + ap2.add_argument("--og-title-i", metavar="T", type=u, default="{{ title }}", help="image title format; takes any metadata key (volflag=og_title_i)") + ap2.add_argument("--og-s-title", action="store_true", help="force default title; do not read from tags (volflag=og_s_title)") ap2.add_argument("--og-desc", metavar="TXT", type=u, default="", help="description text; same for all files, disable with [\033[32m-\033[0m] (volflag=og_desc)") ap2.add_argument("--og-site", metavar="TXT", type=u, default="", help="sitename; defaults to \033[33m--name\033[0m, disable with [\033[32m-\033[0m] (volflag=og_site)") + ap2.add_argument("--tcolor", metavar="RGB", type=u, default="333", help="accent color (3 or 6 hex digits); may also affect safari and/or android-chrome (volflag=tcolor)") ap2.add_argument("--uqe", action="store_true", help="query-string parceling; translate a request for \033[33m/foo/.uqe/BASE64\033[0m into \033[33m/foo?TEXT\033[0m, or \033[33m/foo/?TEXT\033[0m if the first character in \033[33mTEXT\033[0m is a slash. Automatically enabled for \033[33m--og\033[0m") diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index e2a95aa3..e6b35a0c 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -1442,6 +1442,7 @@ class AuthSrv(object): elif "" not in mount: # there's volumes but no root; make root inaccessible vfs = VFS(self.log_func, "", "", AXS(), {}) + vfs.flags["tcolor"] = self.args.tcolor vfs.flags["d2d"] = True maxdepth = 0 @@ -1780,6 +1781,10 @@ class AuthSrv(object): if vol.flags.get("og"): self.args.uqe = True + zs = str(vol.flags.get("tcolor", "")) + if len(zs) == 3: # fc5 => ffcc55 + vol.flags["tcolor"] = "".join([x*2 for x in zs]) + for k1, k2 in IMPLICATIONS: if k1 in vol.flags: vol.flags[k2] = True diff --git a/copyparty/cfg.py b/copyparty/cfg.py index a5da4dcc..d8f42a0e 100644 --- a/copyparty/cfg.py +++ b/copyparty/cfg.py @@ -41,6 +41,7 @@ def vf_bmap() -> dict[str, str]: "no_sb_lg", "og", "og_no_head", + "og_s_title", "rand", "xdev", "xlink", @@ -71,11 +72,15 @@ def vf_vmap() -> dict[str, str]: "og_site", "og_th", "og_title", + "og_title_a", + "og_title_v", + "og_title_i", "og_tpl", "og_ua", "mv_retry", "rm_retry", "sort", + "tcolor", "unlist", "u2abort", "u2ts", diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index ff82daa7..7fc3c570 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -220,6 +220,7 @@ class HttpCli(object): ka["favico"] = self.args.favico ka["s_name"] = self.args.bname ka["s_doctitle"] = self.args.doctitle + ka["tcolor"] = self.vn.flags["tcolor"] zso = self.vn.flags.get("html_head") if zso: @@ -4807,13 +4808,11 @@ class HttpCli(object): if not vn.flags.get("og_no_head"): ogh = {"twitter:card": "summary"} + title = str(vn.flags.get("og_title") or "") + if thumb: ogh["og:image"] = j2a["og_thumb"] - zso = vn.flags.get("og_title") - if zso: - ogh["og:title"] = str(zso) - zso = vn.flags.get("og_desc") or "" if zso != "-": ogh["og:description"] = str(zso) @@ -4824,15 +4823,16 @@ class HttpCli(object): tagmap = {} if is_au: + title = str(vn.flags.get("og_title_a") or "") ogh["og:type"] = "music.song" ogh["og:audio"] = j2a["og_raw"] tagmap = { - "title": "og:title", "artist": "og:music:musician", "album": "og:music:album", ".dur": "og:music:duration", } elif is_vid: + title = str(vn.flags.get("og_title_v") or "") ogh["og:type"] = "video.other" ogh["og:video"] = j2a["og_raw"] tagmap = { @@ -4840,8 +4840,25 @@ class HttpCli(object): ".dur": "og:video:duration", } elif is_pic: - ogh["og:type"] = "video.other" - ogh["og:image"] = j2a["og_raw"] + title = str(vn.flags.get("og_title_i") or "") + ogh["og:type"] = "website" + ogh["twitter:card"] = "photo" + ogh["twitter:image:src"] = ogh["og:image"] = j2a["og_raw"] + + try: + for k, v in file["tags"].items(): + zs = "{{ %s }}" % (k,) + title = title.replace(zs, str(v)) + except: + pass + title = re.sub(r"\{\{ [^}]+ \}\}", "", title) + while title.startswith(" - "): + title = title[3:] + while title.endswith(" - "): + title = title[:3] + + if vn.flags.get("og_s_title"): + title = str(vn.flags.get("og_title") or "") for tag, hname in tagmap.items(): try: @@ -4852,6 +4869,8 @@ class HttpCli(object): except: pass + ogh["og:title"] = title + zs = '\t' oghs = [zs % (k, html_escape(str(v))) for k, v in ogh.items()] zs = self.html_head + "\n%s\n" % ("\n".join(oghs),) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 76f6fcca..e479fa0c 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -6,7 +6,7 @@