from functools import partial from django.conf import settings from django.contrib.auth.context_processors import PermWrapper from django.contrib.sites.shortcuts import get_current_site from django.core.cache import cache from django.utils.functional import SimpleLazyObject, new_method_proxy from judge.utils.caniuse import CanIUse, SUPPORT from .models import MiscConfig, NavigationBar, Profile class FixedSimpleLazyObject(SimpleLazyObject): if not hasattr(SimpleLazyObject, "__iter__"): __iter__ = new_method_proxy(iter) def get_resource(request): use_https = settings.DMOJ_SSL if use_https == 1: scheme = "https" if request.is_secure() else "http" elif use_https > 1: scheme = "https" else: scheme = "http" return { "PYGMENT_THEME": settings.PYGMENT_THEME, "INLINE_JQUERY": settings.INLINE_JQUERY, "INLINE_FONTAWESOME": settings.INLINE_FONTAWESOME, "JQUERY_JS": settings.JQUERY_JS, "FONTAWESOME_CSS": settings.FONTAWESOME_CSS, "DMOJ_SCHEME": scheme, "DMOJ_CANONICAL": settings.DMOJ_CANONICAL, } def get_profile(request): if request.user.is_authenticated: return Profile.objects.get_or_create(user=request.user)[0] return None def comet_location(request): if request.is_secure(): websocket = getattr(settings, "EVENT_DAEMON_GET_SSL", settings.EVENT_DAEMON_GET) poll = getattr(settings, "EVENT_DAEMON_POLL_SSL", settings.EVENT_DAEMON_POLL) else: websocket = settings.EVENT_DAEMON_GET poll = settings.EVENT_DAEMON_POLL return {"EVENT_DAEMON_LOCATION": websocket, "EVENT_DAEMON_POLL_LOCATION": poll} def __nav_tab(path): result = list( NavigationBar.objects.extra(where=["%s REGEXP BINARY regex"], params=[path])[:1] ) return ( result[0].get_ancestors(include_self=True).values_list("key", flat=True) if result else [] ) def general_info(request): path = request.get_full_path() return { "nav_tab": FixedSimpleLazyObject(partial(__nav_tab, request.path)), "nav_bar": NavigationBar.objects.all(), "LOGIN_RETURN_PATH": "" if path.startswith("/accounts/") else path, "perms": PermWrapper(request.user), } def site(request): return {"site": get_current_site(request)} class MiscConfigDict(dict): __slots__ = ("language", "site") def __init__(self, language="", domain=None): self.language = language self.site = domain super(MiscConfigDict, self).__init__() def __missing__(self, key): cache_key = "misc_config:%s:%s:%s" % (self.site, self.language, key) value = cache.get(cache_key) if value is None: keys = ["%s.%s" % (key, self.language), key] if self.language else [key] if self.site is not None: keys = ["%s:%s" % (self.site, key) for key in keys] + keys map = dict( MiscConfig.objects.values_list("key", "value").filter(key__in=keys) ) for item in keys: if item in map: value = map[item] break else: value = "" cache.set(cache_key, value, 86400) self[key] = value return value def misc_config(request): domain = get_current_site(request).domain return { "misc_config": MiscConfigDict(domain=domain), "i18n_config": MiscConfigDict(language=request.LANGUAGE_CODE, domain=domain), } def site_name(request): return { "SITE_NAME": settings.SITE_NAME, "SITE_LONG_NAME": settings.SITE_LONG_NAME, "SITE_ADMIN_EMAIL": settings.SITE_ADMIN_EMAIL, } def math_setting(request): caniuse = CanIUse(request.META.get("HTTP_USER_AGENT", "")) if request.user.is_authenticated: engine = request.profile.math_engine else: engine = settings.MATHOID_DEFAULT_TYPE if engine == "auto": engine = ( "mml" if bool(settings.MATHOID_URL) and caniuse.mathml == SUPPORT else "jax" ) return {"MATH_ENGINE": engine, "REQUIRE_JAX": engine == "jax", "caniuse": caniuse}