diff --git a/glance-system/glance-kisfenyo.yaml b/glance-system/glance-kisfenyo.yaml index cff0dc6..98ce881 100644 --- a/glance-system/glance-kisfenyo.yaml +++ b/glance-system/glance-kisfenyo.yaml @@ -36,7 +36,7 @@ data: server: host: 0.0.0.0 port: 8080 - assets-path: /app/config/assets + assets-path: /app/assets document: head: | @@ -123,22 +123,28 @@ data: } function indexLinks() { - // Prefer bookmarks widgets; fallback to any link inside widgets if Glance changes classes. - const anchors = - Array.from(document.querySelectorAll('.widget.widget-type-bookmarks a[href]')).length - ? document.querySelectorAll('.widget.widget-type-bookmarks a[href]') - : document.querySelectorAll('.widget a[href]'); + const BOOKMARKS_INDEX_URL = '/assets/bookmarks.json'; - indexed = Array.from(anchors) - .map(a => ({ - title: (a.textContent || '').trim(), - url: a.href - })) - .filter(x => x.title || x.url); + async function loadBookmarksIndex() { + try { + const res = await fetch(BOOKMARKS_INDEX_URL, { cache: 'no-store' }); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); - // Deduplicate by URL - const seen = new Set(); - indexed = indexed.filter(x => (seen.has(x.url) ? false : seen.add(x.url))); + // Convert to the format your script already uses + indexed = data.map(x => ({ + title: x.title, + url: x.url, + meta: [x.page, x.widget, x.group].filter(Boolean).join(' • ') + })); + } catch (e) { + console.warn('Could not load bookmarks index, falling back to DOM only:', e); + indexLinksFromDom(); // keep your current DOM indexer as fallback + } + } + + // call once on load + document.addEventListener('DOMContentLoaded', loadBookmarksIndex); } function score(item, q) { @@ -1956,6 +1962,62 @@ spec: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 + initContainers: + - name: build-bookmarks-index + image: python:3.12-alpine + command: ["/bin/sh", "-c"] + args: + - | + pip install --no-cache-dir pyyaml >/dev/null + python - <<'PY' + import json, os, yaml + + cfg = yaml.safe_load(open('/config/glance.yml', 'r', encoding='utf-8')) + items = [] + + for page in cfg.get('pages', []): + page_name = page.get('name', '') + for col in page.get('columns', []): + for w in col.get('widgets', []): + if w.get('type') != 'bookmarks': + continue + widget_title = w.get('title', '') + for g in w.get('groups', []): + group_title = g.get('title', '') + for l in g.get('links', []): + title = (l.get('title') or '').strip() + url = (l.get('url') or '').strip() + if not url: + continue + items.append({ + "title": title or url, + "url": url, + "page": page_name, + "widget": widget_title, + "group": group_title, + }) + + # de-dupe by URL (keep first) + seen = set() + out = [] + for it in items: + if it["url"] in seen: + continue + seen.add(it["url"]) + out.append(it) + + os.makedirs('/app/assets', exist_ok=True) + with open('/app/assets/bookmarks.json', 'w', encoding='utf-8') as f: + json.dump(out, f, ensure_ascii=False, indent=2) + + print(f"Wrote {len(out)} bookmarks -> /app/assets/bookmarks.json") + PY + volumeMounts: + - name: config + mountPath: /config + readOnly: true + - name: assets + mountPath: /app/assets containers: - name: glance image: glanceapp/glance:v0.8.4 @@ -2007,16 +2069,20 @@ spec: cpu: 200m memory: 128Mi volumeMounts: + - name: assets + mountPath: /app/assets - name: config mountPath: /app/config/glance.yml subPath: glance.yml - name: config - mountPath: /app/config/assets/custom.css + mountPath: /app/assets/custom.css subPath: custom.css volumes: - name: config configMap: name: glance-config-kisfenyo + - name: assets + emptyDir: {} --- apiVersion: v1 kind: Service