Files
links/core/urls.py
T
2026-04-16 14:01:43 +10:00

73 lines
3.0 KiB
Python

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.static import serve
from django.views.generic import TemplateView
from django.http import FileResponse, Http404
from links.views import LinkDetailView, LinkUpdateView, CustomLinkView
from links.file_views import PublicFileView, import_image_view
from django.urls import path, include, re_path
from django.conf.urls.i18n import i18n_patterns
import os
def _serve_static_file(filename, content_type):
"""Serve a file directly from the committed static/ directory."""
def view(request):
path = os.path.join(settings.BASE_DIR, 'static', filename)
try:
return FileResponse(open(path, 'rb'), content_type=content_type)
except FileNotFoundError:
raise Http404
return view
urlpatterns = [
# LLM-friendly discovery endpoints — must be FIRST before any catch-all routes
path('llms.txt', _serve_static_file('llms.txt', 'text/plain; charset=utf-8'), name='llms-txt'),
path('.well-known/ai-plugin.json', _serve_static_file('.well-known/ai-plugin.json', 'application/json'), name='ai-plugin-json'),
path('admin/', admin.site.urls),
# Add API URLs before locale URLs
path('api/', include('links.api_urls')), # New line for API routes
# Media files
path('media/<path:path>', serve, {
'document_root': settings.MEDIA_ROOT,
}),
# Music files
path('music/<path:path>', serve, {
'document_root': settings.MUSIC_ROOT,
}),
path('i18n/', include('django.conf.urls.i18n')),
path('search/', include('links.search_urls')),
path('link/<int:pk>/', LinkDetailView.as_view(), name='link_detail'),
path('link/<int:pk>/edit/', LinkUpdateView.as_view(), name='link_update'),
path('custom/<slug:alias>/', CustomLinkView.as_view(), name='custom_link'),
path('custom/<slug:alias>/edit/', LinkUpdateView.as_view(), name='custom_link_update'),
# Include netscan and files BEFORE links.urls to prevent the alias catch-all from intercepting them
path('ui/netscan/', include('netscan.urls')),
path('ui/nginxmon/', include('nginxmon.urls')),
path('ui/routermon/', include('routermon.urls')),
path('ui/files/', include('links.file_urls')),
# Import external image by URL — /import/images/<path:image_url> (also plural alias)
path('import/images/<path:image_url>', import_image_view, name='import-image'),
path('imports/images/<path:image_url>', import_image_view, name='imports-image'),
# Public file access — /public/files/{uuid}-{filename}
re_path(
r'^public/files/(?P<pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})-(?P<filename>.+)$',
PublicFileView.as_view(),
name='public-file',
),
# Include main app URLs with locale
path('', include('links.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)