Expose /sitemap-user-products.xml when customer_products is enabled, invalidate on listing mutations, and proxy the new path from nginx provision scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
114 lines
3.1 KiB
Bash
Executable File
114 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Insert / update Meshkee SEO proxy locations on an existing storefront nginx site.
|
|
# Covers HTTP + HTTPS server blocks: sitemap index, child sitemaps, robots.txt
|
|
set -euo pipefail
|
|
|
|
HOST="${1:-}"
|
|
API_HOST="${MESHKEE_API_HOST:-api.meshkee.com}"
|
|
|
|
if [[ -z "$HOST" ]]; then
|
|
echo "usage: patch-nginx-seo.sh <host>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
NGINX_AVAILABLE="/etc/nginx/sites-available/$HOST"
|
|
|
|
if [[ ! -f "$NGINX_AVAILABLE" ]]; then
|
|
echo "missing nginx site for $HOST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
python3 - "$NGINX_AVAILABLE" "$HOST" "$API_HOST" <<'PY'
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
path = Path(sys.argv[1])
|
|
host = sys.argv[2]
|
|
api = sys.argv[3]
|
|
text = path.read_text()
|
|
|
|
paths = [
|
|
("/sitemap.xml", "sitemap.xml"),
|
|
("/sitemap-main.xml", "sitemap-main.xml"),
|
|
("/sitemap-products.xml", "sitemap-products.xml"),
|
|
("/sitemap-blogs.xml", "sitemap-blogs.xml"),
|
|
("/sitemap-portfolios.xml", "sitemap-portfolios.xml"),
|
|
("/sitemap-videos.xml", "sitemap-videos.xml"),
|
|
("/sitemap-instructions.xml", "sitemap-instructions.xml"),
|
|
("/sitemap-workshops.xml", "sitemap-workshops.xml"),
|
|
("/sitemap-user-products.xml", "sitemap-user-products.xml"),
|
|
("/robots.txt", "robots.txt"),
|
|
]
|
|
|
|
def block(loc: str, upstream: str) -> str:
|
|
return (
|
|
f" location = {loc} {{\n"
|
|
f" proxy_pass https://{api}/api/v1/tenants/{host}/{upstream};\n"
|
|
f" proxy_set_header Host {api};\n"
|
|
f" proxy_ssl_server_name on;\n"
|
|
f" proxy_set_header X-Real-IP $remote_addr;\n"
|
|
f" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"
|
|
f" proxy_set_header X-Forwarded-Proto $scheme;\n"
|
|
f" add_header Cache-Control \"public, max-age=900\";\n"
|
|
f" }}\n\n"
|
|
)
|
|
|
|
parts: list[tuple[str, str]] = []
|
|
idx = 0
|
|
while True:
|
|
start = text.find("server {", idx)
|
|
if start < 0:
|
|
parts.append(("tail", text[idx:]))
|
|
break
|
|
if start > idx:
|
|
parts.append(("other", text[idx:start]))
|
|
i = start + len("server {")
|
|
depth = 1
|
|
while i < len(text) and depth:
|
|
if text[i] == "{":
|
|
depth += 1
|
|
elif text[i] == "}":
|
|
depth -= 1
|
|
i += 1
|
|
parts.append(("server", text[start:i]))
|
|
idx = i
|
|
|
|
changed = False
|
|
out: list[str] = []
|
|
for kind, chunk in parts:
|
|
if kind != "server":
|
|
out.append(chunk)
|
|
continue
|
|
|
|
server = chunk
|
|
if host not in server:
|
|
out.append(server)
|
|
continue
|
|
|
|
insert_at = server.find(" location / {")
|
|
if insert_at < 0:
|
|
insert_at = server.find("\tlocation / {")
|
|
if insert_at < 0:
|
|
out.append(server)
|
|
continue
|
|
|
|
additions = ""
|
|
for loc, upstream in paths:
|
|
if f"location = {loc}" not in server:
|
|
additions += block(loc, upstream)
|
|
changed = True
|
|
if additions:
|
|
server = server[:insert_at] + additions + server[insert_at:]
|
|
out.append(server)
|
|
|
|
if changed:
|
|
path.write_text("".join(out))
|
|
print(f"updated: {host}")
|
|
else:
|
|
print(f"already present: {host}")
|
|
PY
|
|
|
|
nginx -t
|
|
systemctl reload nginx
|
|
echo "patched nginx SEO locations for $HOST"
|