ixg_platform/apps/guides/management/commands/sync_guides.py
ixgadmin d74f0814da Finish the wiki root move, zone map view and spec approval
- Follow home/user-guides/ through one GUIDE_PATH_PREFIX constant.
- Add a read-only Origin Zone detail view with the map as the main panel.
- Name due diligence explicitly and add its section headings.
- Add admin-only, four-eyes specification approval (portal and API).
- Empty the New-zone geometry placeholder instead of showing null.
2026-10-27 17:41:08 +00:00

75 lines
2.5 KiB
Python

from django.core.management.base import BaseCommand
from django.db import connections
from django.utils import timezone
from django.utils.dateparse import parse_datetime
from apps.guides.models import GUIDE_PATH_PREFIX, GuidePage
SELECT_PAGES_SQL = (
'SELECT path, title, content, "updatedAt" FROM pages '
'WHERE path LIKE %s AND "isPublished" = true AND "isPrivate" = false'
)
class Command(BaseCommand):
help = "One-way sync of Wiki.js guide pages into GuidePage (read-only on wikijs)."
def handle(self, *args, **options):
created = 0
updated = 0
stale = []
existing = {page.path: page for page in GuidePage.objects.all()}
known_paths = set()
with connections["wikijs"].cursor() as cursor:
cursor.execute(SELECT_PAGES_SQL, [f"{GUIDE_PATH_PREFIX}%"])
rows = cursor.fetchall()
for path, title, content, updated_at_raw in rows:
audience = GuidePage.map_audience(path)
if audience is None:
continue
known_paths.add(path)
parsed = parse_datetime(updated_at_raw) if updated_at_raw else None
updated_at = parsed or timezone.now()
page = existing.pop(path, None)
if page is None:
GuidePage.objects.create(
path=path,
title=title,
audience=audience,
content=content,
updated_at=updated_at,
)
created += 1
continue
changed = (
page.title != title
or page.content != content
or page.audience != audience
or page.updated_at != updated_at
)
if changed:
page.title = title
page.content = content
page.audience = audience
page.updated_at = updated_at
page.save(update_fields=["title", "content", "audience", "updated_at", "synced_at"])
updated += 1
removed = 0
for path in existing:
if path not in known_paths:
stale.append(path)
if stale:
removed = GuidePage.objects.filter(path__in=stale).delete()[0]
self.stdout.write(
self.style.SUCCESS(
f"sync_guides complete: {created} created, {updated} updated, {removed} removed."
)
)
self.stdout.write(f"Total GuidePage rows: {GuidePage.objects.count()}.")