1
0
forked from erp-dev/erp
Files
erpnew/api_v1/utils/media.py

68 lines
1.9 KiB
Python

"""Helper utilities for building public media URLs."""
from __future__ import annotations
from urllib.parse import urlparse, urlunparse
from django.conf import settings
def _get_storage_base_url() -> str | None:
"""
Return the base URL (scheme + domain) for public media files based on Qiniu settings.
The returned URL never ends with a slash.
"""
domain = getattr(settings, 'QINIU_BUCKET_DOMAIN', '') or ''
domain = domain.strip().rstrip('/')
if not domain:
return None
if domain.startswith('http://') or domain.startswith('https://'):
base = domain
else:
scheme = 'https' if getattr(settings, 'QINIU_SECURE_URL', False) else 'http'
base = f'{scheme}://{domain}'
return base.rstrip('/')
def build_public_media_url(value: str | None, *, request=None) -> str | None:
"""
Normalize any stored media reference (absolute URL or relative path) to the currently
configured bucket domain. Falls back to request host or the original value when the
bucket domain is unavailable.
"""
if value is None:
return None
value = str(value).strip()
if not value:
return None
base = _get_storage_base_url()
parsed = urlparse(value)
if parsed.scheme and parsed.netloc:
if not base:
return value
base_parts = urlparse(base)
return urlunparse(
(
base_parts.scheme or parsed.scheme or 'http',
base_parts.netloc or parsed.netloc,
parsed.path or '',
parsed.params,
parsed.query,
parsed.fragment,
)
)
path = value if value.startswith('/') else f'/{value}'
if base:
return f'{base}{path}'
if request is not None:
return request.build_absolute_uri(path)
return path
__all__ = ['build_public_media_url']