opengraph stuff:

* template-based title formatting
* picture embeds are no longer ant-sized
* `--og-color` sets accent color; default #333
* `--og-s-title` forces default title, ignoring e2t
* add a music indicator to song titles because discord doesn't
This commit is contained in:
ed 2024-05-03 00:11:40 +00:00
parent 69517e4624
commit 36f2c446af
12 changed files with 52 additions and 18 deletions

View file

@ -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 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 ## file indexing

View file

@ -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-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 <head> (useful if you're doing this yourself in a template or such) (volflag=og_no_head)") ap2.add_argument("--og-no-head", action="store_true", help="do not automatically add OG entries into <head> (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-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-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("--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") 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")

View file

@ -1442,6 +1442,7 @@ class AuthSrv(object):
elif "" not in mount: elif "" not in mount:
# there's volumes but no root; make root inaccessible # there's volumes but no root; make root inaccessible
vfs = VFS(self.log_func, "", "", AXS(), {}) vfs = VFS(self.log_func, "", "", AXS(), {})
vfs.flags["tcolor"] = self.args.tcolor
vfs.flags["d2d"] = True vfs.flags["d2d"] = True
maxdepth = 0 maxdepth = 0
@ -1780,6 +1781,10 @@ class AuthSrv(object):
if vol.flags.get("og"): if vol.flags.get("og"):
self.args.uqe = True 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: for k1, k2 in IMPLICATIONS:
if k1 in vol.flags: if k1 in vol.flags:
vol.flags[k2] = True vol.flags[k2] = True

View file

@ -41,6 +41,7 @@ def vf_bmap() -> dict[str, str]:
"no_sb_lg", "no_sb_lg",
"og", "og",
"og_no_head", "og_no_head",
"og_s_title",
"rand", "rand",
"xdev", "xdev",
"xlink", "xlink",
@ -71,11 +72,15 @@ def vf_vmap() -> dict[str, str]:
"og_site", "og_site",
"og_th", "og_th",
"og_title", "og_title",
"og_title_a",
"og_title_v",
"og_title_i",
"og_tpl", "og_tpl",
"og_ua", "og_ua",
"mv_retry", "mv_retry",
"rm_retry", "rm_retry",
"sort", "sort",
"tcolor",
"unlist", "unlist",
"u2abort", "u2abort",
"u2ts", "u2ts",

View file

@ -220,6 +220,7 @@ class HttpCli(object):
ka["favico"] = self.args.favico ka["favico"] = self.args.favico
ka["s_name"] = self.args.bname ka["s_name"] = self.args.bname
ka["s_doctitle"] = self.args.doctitle ka["s_doctitle"] = self.args.doctitle
ka["tcolor"] = self.vn.flags["tcolor"]
zso = self.vn.flags.get("html_head") zso = self.vn.flags.get("html_head")
if zso: if zso:
@ -4807,13 +4808,11 @@ class HttpCli(object):
if not vn.flags.get("og_no_head"): if not vn.flags.get("og_no_head"):
ogh = {"twitter:card": "summary"} ogh = {"twitter:card": "summary"}
title = str(vn.flags.get("og_title") or "")
if thumb: if thumb:
ogh["og:image"] = j2a["og_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 "" zso = vn.flags.get("og_desc") or ""
if zso != "-": if zso != "-":
ogh["og:description"] = str(zso) ogh["og:description"] = str(zso)
@ -4824,15 +4823,16 @@ class HttpCli(object):
tagmap = {} tagmap = {}
if is_au: if is_au:
title = str(vn.flags.get("og_title_a") or "")
ogh["og:type"] = "music.song" ogh["og:type"] = "music.song"
ogh["og:audio"] = j2a["og_raw"] ogh["og:audio"] = j2a["og_raw"]
tagmap = { tagmap = {
"title": "og:title",
"artist": "og:music:musician", "artist": "og:music:musician",
"album": "og:music:album", "album": "og:music:album",
".dur": "og:music:duration", ".dur": "og:music:duration",
} }
elif is_vid: elif is_vid:
title = str(vn.flags.get("og_title_v") or "")
ogh["og:type"] = "video.other" ogh["og:type"] = "video.other"
ogh["og:video"] = j2a["og_raw"] ogh["og:video"] = j2a["og_raw"]
tagmap = { tagmap = {
@ -4840,8 +4840,25 @@ class HttpCli(object):
".dur": "og:video:duration", ".dur": "og:video:duration",
} }
elif is_pic: elif is_pic:
ogh["og:type"] = "video.other" title = str(vn.flags.get("og_title_i") or "")
ogh["og:image"] = j2a["og_raw"] 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(): for tag, hname in tagmap.items():
try: try:
@ -4852,6 +4869,8 @@ class HttpCli(object):
except: except:
pass pass
ogh["og:title"] = title
zs = '\t<meta property="%s" content="%s">' zs = '\t<meta property="%s" content="%s">'
oghs = [zs % (k, html_escape(str(v))) for k, v in ogh.items()] oghs = [zs % (k, html_escape(str(v))) for k, v in ogh.items()]
zs = self.html_head + "\n%s\n" % ("\n".join(oghs),) zs = self.html_head + "\n%s\n" % ("\n".join(oghs),)

View file

@ -6,7 +6,7 @@
<title>{{ title }}</title> <title>{{ title }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimum-scale=0.6"> <meta name="viewport" content="width=device-width, initial-scale=0.8, minimum-scale=0.6">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/browser.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/browser.css?_={{ ts }}">
{{ html_head }} {{ html_head }}

View file

@ -3,7 +3,7 @@
<title>📝 {{ title }}</title> <title>📝 {{ title }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.7"> <meta name="viewport" content="width=device-width, initial-scale=0.7">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}"> <link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
<link rel="stylesheet" href="{{ r }}/.cpr/md.css?_={{ ts }}"> <link rel="stylesheet" href="{{ r }}/.cpr/md.css?_={{ ts }}">
{%- if edit %} {%- if edit %}

View file

@ -3,7 +3,7 @@
<title>📝 {{ title }}</title> <title>📝 {{ title }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.7"> <meta name="viewport" content="width=device-width, initial-scale=0.7">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}"> <link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
<link rel="stylesheet" href="{{ r }}/.cpr/mde.css?_={{ ts }}"> <link rel="stylesheet" href="{{ r }}/.cpr/mde.css?_={{ ts }}">
<link rel="stylesheet" href="{{ r }}/.cpr/deps/mini-fa.css?_={{ ts }}"> <link rel="stylesheet" href="{{ r }}/.cpr/deps/mini-fa.css?_={{ ts }}">

View file

@ -6,7 +6,7 @@
<title>{{ s_doctitle }}</title> <title>{{ s_doctitle }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.8"> <meta name="viewport" content="width=device-width, initial-scale=0.8">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/msg.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/msg.css?_={{ ts }}">
{{ html_head }} {{ html_head }}
</head> </head>

View file

@ -6,7 +6,7 @@
<title>{{ s_doctitle }}</title> <title>{{ s_doctitle }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.8"> <meta name="viewport" content="width=device-width, initial-scale=0.8">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
{{ html_head }} {{ html_head }}

View file

@ -6,7 +6,7 @@
<title>{{ s_doctitle }}</title> <title>{{ s_doctitle }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.8"> <meta name="viewport" content="width=device-width, initial-scale=0.8">
<meta name="theme-color" content="#333"> <meta name="theme-color" content="#{{ tcolor }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}">
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}"> <link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
<style>ul{padding-left:1.3em}li{margin:.4em 0}</style> <style>ul{padding-left:1.3em}li{margin:.4em 0}</style>

View file

@ -110,7 +110,7 @@ class Cfg(Namespace):
def __init__(self, a=None, v=None, c=None, **ka0): def __init__(self, a=None, v=None, c=None, **ka0):
ka = {} ka = {}
ex = "daw dav_auth dav_inf dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid hardlink ih ihead magic never_symlink nid nih no_acode no_athumb no_dav no_dedup no_del no_dupe no_lifetime no_logues no_mv no_pipe no_readme no_robots no_sb_md no_sb_lg no_scandir no_tarcmp no_thumb no_vthumb no_zip nrand nw og og_no_head q rand smb srch_dbg stats uqe vague_403 vc ver xdev xlink xvol" ex = "daw dav_auth dav_inf dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid hardlink ih ihead magic never_symlink nid nih no_acode no_athumb no_dav no_dedup no_del no_dupe no_lifetime no_logues no_mv no_pipe no_readme no_robots no_sb_md no_sb_lg no_scandir no_tarcmp no_thumb no_vthumb no_zip nrand nw og og_no_head og_s_title q rand smb srch_dbg stats uqe vague_403 vc ver xdev xlink xvol"
ka.update(**{k: False for k in ex.split()}) ka.update(**{k: False for k in ex.split()})
ex = "dotpart dotsrch no_dhash no_fastboot no_rescan no_sendfile no_snap no_voldump re_dhash plain_ip" ex = "dotpart dotsrch no_dhash no_fastboot no_rescan no_sendfile no_snap no_voldump re_dhash plain_ip"
@ -128,7 +128,7 @@ class Cfg(Namespace):
ex = "db_act df k304 loris re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo" ex = "db_act df k304 loris re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo"
ka.update(**{k: 0 for k in ex.split()}) ka.update(**{k: 0 for k in ex.split()})
ex = "ah_alg bname doctitle exit favico idp_h_usr html_head lg_sbf log_fk md_sbf name og_desc og_site og_th og_title textfiles unlist vname R RS SR" ex = "ah_alg bname doctitle exit favico idp_h_usr html_head lg_sbf log_fk md_sbf name og_desc og_site og_th og_title og_title_a og_title_v og_title_i tcolor textfiles unlist vname R RS SR"
ka.update(**{k: "" for k in ex.split()}) ka.update(**{k: "" for k in ex.split()})
ex = "grp on403 on404 xad xar xau xban xbd xbr xbu xiu xm" ex = "grp on403 on404 xad xar xau xban xbd xbr xbu xiu xm"