Files
links/core/apps.py
T
junvandCopilot 3955e95b9e geo: replace ip-api.com with local DB-IP City Lite MMDB
- Rewrite nginxmon/geo.py to use maxminddb + DB-IP City Lite MMDB
  (https://cdn.jsdelivr.net/npm/dbip-city-lite/dbip-city-lite.mmdb.gz)
  instead of ip-api.com HTTP API — eliminates all network timeouts and
  rate-limit issues; lookups are now sub-millisecond in-process
- Keep _lookup_batch() signature unchanged so routermon receiver
  requires no changes
- MMDB downloaded on first use (lazy) and refreshed monthly via
  APScheduler; reader cached module-level (thread-safe for reads)
- Add management command: manage.py download_geo_db
- Update k8s init container to download MMDB on first deploy if absent
- Add maxminddb==3.1.1 dependency

CC BY 4.0 — DB-IP (https://db-ip.com)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 16:44:02 +10:00

108 lines
4.2 KiB
Python

"""
Core app configuration
"""
from django.apps import AppConfig
import logging
logger = logging.getLogger(__name__)
class CoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'core'
def ready(self):
"""
Initialize APScheduler when Django starts
"""
from core.scheduler import scheduler, start_scheduler
from links.tasks import (
schedule_pending_pages, schedule_pending_screenshots,
retry_stuck_image_imports, flush_click_buffer,
)
from apscheduler.triggers.interval import IntervalTrigger
# Start the scheduler
start_scheduler()
# Read intervals from SiteSettings (fall back to 120s if DB not ready)
try:
from links.models import SiteSettings
ss = SiteSettings.get()
pages_interval = ss.schedule_pending_pages_interval or 120
screenshots_interval = ss.schedule_pending_screenshots_interval or 120
except Exception:
pages_interval = 120
screenshots_interval = 120
# Add periodic job for checking pending pages
scheduler.add_job(
schedule_pending_pages,
trigger=IntervalTrigger(seconds=pages_interval),
id='schedule_pending_pages',
replace_existing=True,
)
logger.info(f"Scheduled periodic task: schedule_pending_pages (every {pages_interval}s)")
# Add periodic job for recovering stuck screenshots
scheduler.add_job(
schedule_pending_screenshots,
trigger=IntervalTrigger(seconds=screenshots_interval),
id='schedule_pending_screenshots',
replace_existing=True,
)
logger.info(f"Scheduled periodic task: schedule_pending_screenshots (every {screenshots_interval}s)")
# Add periodic job for retrying stuck image imports (every 5 minutes)
scheduler.add_job(
retry_stuck_image_imports,
trigger=IntervalTrigger(seconds=300),
id='retry_stuck_image_imports',
replace_existing=True,
)
logger.info("Scheduled periodic task: retry_stuck_image_imports (every 300s)")
# Flush Redis-buffered click counts to the database (every 60 seconds)
scheduler.add_job(
flush_click_buffer,
trigger=IntervalTrigger(seconds=60),
id='flush_click_buffer',
replace_existing=True,
)
logger.info("Scheduled periodic task: flush_click_buffer (every 60s)")
# ── nginxmon: monthly geo DB refresh ──────────────────────────────────
try:
from nginxmon.geo import download_geo_db as refresh_geo_db
scheduler.add_job(
refresh_geo_db,
trigger=IntervalTrigger(days=30),
id='refresh_geo_db',
replace_existing=True,
)
logger.info('nginxmon: scheduled geo DB refresh (every 30 days)')
except Exception as exc:
logger.warning('nginxmon: geo DB scheduler setup failed: %s', exc)
# ── routermon ──────────────────────────────────────────────────────────
try:
from routermon.tasks import cleanup_old_queries
from routermon.models import RouterMonSettings
from routermon.receiver import start_receiver
rm_settings = RouterMonSettings.get()
if rm_settings.enabled:
start_receiver(rm_settings.syslog_port)
scheduler.add_job(
cleanup_old_queries,
trigger=IntervalTrigger(hours=6),
id='routermon_cleanup',
replace_existing=True,
)
logger.info("routermon: scheduled cleanup job (every 6h)")
except Exception as exc:
import sys
print(f'routermon: startup error (non-fatal): {exc}', file=sys.stderr, flush=True)
logger.warning("routermon: startup error (non-fatal): %s", exc)