added initcontainer for collecting bookmarks
This commit is contained in:
@@ -36,7 +36,7 @@ data:
|
|||||||
server:
|
server:
|
||||||
host: 0.0.0.0
|
host: 0.0.0.0
|
||||||
port: 8080
|
port: 8080
|
||||||
assets-path: /app/config/assets
|
assets-path: /app/assets
|
||||||
|
|
||||||
document:
|
document:
|
||||||
head: |
|
head: |
|
||||||
@@ -123,22 +123,28 @@ data:
|
|||||||
}
|
}
|
||||||
|
|
||||||
function indexLinks() {
|
function indexLinks() {
|
||||||
// Prefer bookmarks widgets; fallback to any link inside widgets if Glance changes classes.
|
const BOOKMARKS_INDEX_URL = '/assets/bookmarks.json';
|
||||||
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]');
|
|
||||||
|
|
||||||
indexed = Array.from(anchors)
|
async function loadBookmarksIndex() {
|
||||||
.map(a => ({
|
try {
|
||||||
title: (a.textContent || '').trim(),
|
const res = await fetch(BOOKMARKS_INDEX_URL, { cache: 'no-store' });
|
||||||
url: a.href
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||||
}))
|
const data = await res.json();
|
||||||
.filter(x => x.title || x.url);
|
|
||||||
|
|
||||||
// Deduplicate by URL
|
// Convert to the format your script already uses
|
||||||
const seen = new Set();
|
indexed = data.map(x => ({
|
||||||
indexed = indexed.filter(x => (seen.has(x.url) ? false : seen.add(x.url)));
|
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) {
|
function score(item, q) {
|
||||||
@@ -1956,6 +1962,62 @@ spec:
|
|||||||
runAsUser: 1000
|
runAsUser: 1000
|
||||||
runAsGroup: 1000
|
runAsGroup: 1000
|
||||||
fsGroup: 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:
|
containers:
|
||||||
- name: glance
|
- name: glance
|
||||||
image: glanceapp/glance:v0.8.4
|
image: glanceapp/glance:v0.8.4
|
||||||
@@ -2007,16 +2069,20 @@ spec:
|
|||||||
cpu: 200m
|
cpu: 200m
|
||||||
memory: 128Mi
|
memory: 128Mi
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
- name: assets
|
||||||
|
mountPath: /app/assets
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /app/config/glance.yml
|
mountPath: /app/config/glance.yml
|
||||||
subPath: glance.yml
|
subPath: glance.yml
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /app/config/assets/custom.css
|
mountPath: /app/assets/custom.css
|
||||||
subPath: custom.css
|
subPath: custom.css
|
||||||
volumes:
|
volumes:
|
||||||
- name: config
|
- name: config
|
||||||
configMap:
|
configMap:
|
||||||
name: glance-config-kisfenyo
|
name: glance-config-kisfenyo
|
||||||
|
- name: assets
|
||||||
|
emptyDir: {}
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|||||||
Reference in New Issue
Block a user