dynamicweb/cms/utils/apphook_reload.py

105 lines
2.9 KiB
Python

import logging
import sys
import uuid
# Py2 and Py3 compatible reload
from importlib import reload
from threading import local
from django.conf import settings
from django.urls import clear_url_caches
logger = logging.getLogger("cms")
_urlconf_revision = {}
_urlconf_revision_threadlocal = local()
use_threadlocal = False
def ensure_urlconf_is_up_to_date():
global_revision = get_global_revision()
local_revision = get_local_revision()
if not local_revision:
set_local_revision(global_revision)
elif global_revision != local_revision:
if settings.DEBUG:
log_reloading_apphook(global_revision, local_revision)
debug_check_url('my_test_app_view')
reload_urlconf(new_revision=global_revision)
if settings.DEBUG:
debug_check_url('my_test_app_view')
def get_local_revision(default=None):
if use_threadlocal:
return getattr(_urlconf_revision_threadlocal, "value", default)
else:
return _urlconf_revision.get('urlconf_revision', default)
def set_local_revision(revision):
if use_threadlocal:
if revision:
_urlconf_revision_threadlocal.value = revision
else:
if hasattr(_urlconf_revision_threadlocal, "value"):
del _urlconf_revision_threadlocal.value
else:
_urlconf_revision['urlconf_revision'] = revision
def get_global_revision():
from ..models import UrlconfRevision
revision, _ = UrlconfRevision.get_or_create_revision(
revision=str(uuid.uuid4()))
return revision
def set_global_revision(new_revision=None):
from ..models import UrlconfRevision
if new_revision is None:
new_revision = str(uuid.uuid4())
UrlconfRevision.update_revision(new_revision)
def mark_urlconf_as_changed():
new_revision = str(uuid.uuid4())
set_global_revision(new_revision=new_revision)
return new_revision
def reload_urlconf(urlconf=None, new_revision=None):
from cms.appresolver import clear_app_resolvers, get_app_patterns
if 'cms.urls' in sys.modules:
reload(sys.modules['cms.urls'])
if urlconf is None:
urlconf = settings.ROOT_URLCONF
if urlconf in sys.modules:
reload(sys.modules[urlconf])
clear_app_resolvers()
clear_url_caches()
get_app_patterns()
if new_revision is not None:
set_local_revision(new_revision)
def log_reloading_apphook(global_revision, local_revision):
logger.debug(f" New revision!!!! RELOAD!\n"
f" {global_revision} ({type(global_revision)})\n"
f" -> {local_revision} ({type(local_revision)})")
def debug_check_url(url_name):
from django.urls import reverse
try:
debug_msg = " reverse('{}'): {} ".format(
url_name,
reverse('my_test_app_view'),
)
except Exception as e:
debug_msg = f" ERROR: reverse('{url_name}'): {e}"
logger.debug(debug_msg)