django-cms-qe 3.7.0__py3-none-any.whl → 3.7.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cms_qe/boilerplates/bootstrap3/templates/cms_qe/home.html +3 -3
- cms_qe/export.py +7 -8
- cms_qe/settings/base/app.py +4 -12
- cms_qe/settings/base/cache.py +4 -6
- cms_qe/settings/base/cms.py +1 -4
- cms_qe/settings/base/constants.py +11 -0
- cms_qe/settings/base/database.py +10 -7
- cms_qe/settings/base/email.py +11 -9
- cms_qe/settings/base/logging.py +1 -2
- cms_qe/settings/base/search.py +1 -5
- cms_qe/settings/base/security.py +1 -2
- cms_qe/settings/dev.py +19 -25
- cms_qe/templates/base.html +4 -7
- cms_qe/templates/cms_qe/home.html +2 -0
- cms_qe/utils.py +17 -11
- cms_qe/views/redirect_to_page.py +8 -19
- cms_qe_auth/models.py +1 -1
- cms_qe_test/cms.py +5 -22
- {django_cms_qe-3.7.0.dist-info → django_cms_qe-3.7.2.dist-info}/METADATA +22 -61
- {django_cms_qe-3.7.0.dist-info → django_cms_qe-3.7.2.dist-info}/RECORD +30 -32
- {django_cms_qe-3.7.0.dist-info → django_cms_qe-3.7.2.dist-info}/top_level.txt +1 -0
- example/__init__.py +0 -0
- example/settings/__init__.py +0 -0
- example/settings/aldryn_newsblog.py +14 -0
- example/settings/dev.py +29 -0
- example/settings/selenium.py +10 -0
- example/urls.py +16 -0
- example/wsgi.py +16 -0
- cms_qe/hooks.py +0 -90
- cms_qe/ldap.py +0 -4
- cms_qe/settings/base/env.py +0 -3
- cms_qe/static/cms_qe/css/fix-djangocms-admin-style.css +0 -33
- cms_qe/templates/admin/inc/extrastyle.html +0 -2
- cms_qe/templates/cms_qe/alias_content_preview.html +0 -28
- cms_qe/templates/pg_is_in_recovery_login.html +0 -4
- cms_qe/views/test_messages.py +0 -32
- cms_qe_test/mail_filebased_backend.py +0 -20
- {django_cms_qe-3.7.0.dist-info → django_cms_qe-3.7.2.dist-info}/WHEEL +0 -0
- {django_cms_qe-3.7.0.dist-info → django_cms_qe-3.7.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% load static i18n cms_tags sekizai_tags
|
|
1
|
+
{% load static i18n cms_tags sekizai_tags %}
|
|
2
2
|
|
|
3
3
|
{% addtoblock "css" %}
|
|
4
4
|
<link rel="stylesheet" href="{% static "cms_qe/css/bootstrap.min.css" %}" />
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
{% block header %}
|
|
28
28
|
<header>
|
|
29
|
-
{%
|
|
29
|
+
{% static_placeholder "header" %}
|
|
30
30
|
</header>
|
|
31
31
|
{% endblock %}
|
|
32
32
|
{% block content %}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
{% endblock %}
|
|
37
37
|
{% block footers %}
|
|
38
38
|
<footer>
|
|
39
|
-
{%
|
|
39
|
+
{% static_placeholder "footer" %}
|
|
40
40
|
</footer>
|
|
41
41
|
{% endblock %}
|
|
42
42
|
|
cms_qe/export.py
CHANGED
|
@@ -137,7 +137,7 @@ def export_data(export_type, modeladmin, queryset):
|
|
|
137
137
|
if not field.auto_created or field.name == 'id'
|
|
138
138
|
]
|
|
139
139
|
|
|
140
|
-
def get_export_headers(self
|
|
140
|
+
def get_export_headers(self) -> list:
|
|
141
141
|
"""
|
|
142
142
|
As header use verbose name which is better than database name.
|
|
143
143
|
"""
|
|
@@ -153,8 +153,8 @@ def export_data(export_type, modeladmin, queryset):
|
|
|
153
153
|
name = force_str(field.verbose_name)
|
|
154
154
|
return name
|
|
155
155
|
|
|
156
|
-
def export_field(self, field,
|
|
157
|
-
value = super().export_field(field,
|
|
156
|
+
def export_field(self, field, obj):
|
|
157
|
+
value = super().export_field(field, obj)
|
|
158
158
|
if '__proxy__' in value.__class__.__name__:
|
|
159
159
|
value = force_str(value)
|
|
160
160
|
return value
|
|
@@ -176,11 +176,11 @@ class AdminField(fields.Field):
|
|
|
176
176
|
self.get_modeladmin = lambda: modeladmin
|
|
177
177
|
super().__init__(*args, **kwds)
|
|
178
178
|
|
|
179
|
-
def get_value(self,
|
|
179
|
+
def get_value(self, obj):
|
|
180
180
|
admin_property = getattr(self.get_modeladmin(), self.attribute, None)
|
|
181
181
|
if admin_property:
|
|
182
|
-
return admin_property(
|
|
183
|
-
return super().get_value(
|
|
182
|
+
return admin_property(obj)
|
|
183
|
+
return super().get_value(obj)
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
# Taken from https://github.com/django-import-export/django-import-export/issues/525#issuecomment-303046691
|
|
@@ -197,13 +197,12 @@ class ChoicesWidget(widgets.Widget):
|
|
|
197
197
|
"""
|
|
198
198
|
self.choices = dict(choices)
|
|
199
199
|
self.revert_choices = {v: k for k, v in self.choices.items()}
|
|
200
|
-
super().__init__()
|
|
201
200
|
|
|
202
201
|
# pylint: disable=keyword-arg-before-vararg
|
|
203
202
|
def clean(self, value, row=None, *args, **kwargs):
|
|
204
203
|
"""Returns the db value given the display value"""
|
|
205
204
|
return self.revert_choices.get(value, value) if value else None
|
|
206
205
|
|
|
207
|
-
def render(self, value, obj=None
|
|
206
|
+
def render(self, value, obj=None):
|
|
208
207
|
"""Returns the display value given the db value"""
|
|
209
208
|
return self.choices.get(value, '')
|
cms_qe/settings/base/app.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Base settings for Django app.
|
|
3
3
|
"""
|
|
4
|
-
from .env import ENV
|
|
5
4
|
|
|
6
5
|
# Default primary key field type
|
|
7
6
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
|
@@ -9,10 +8,8 @@ from .env import ENV
|
|
|
9
8
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
10
9
|
|
|
11
10
|
SITE_ID = 1
|
|
12
|
-
CMS_CONFIRM_VERSION4 = True
|
|
13
|
-
DJANGOCMS_VERSIONING_ALLOW_DELETING_VERSIONS = True
|
|
14
11
|
|
|
15
|
-
INTERNAL_IPS =
|
|
12
|
+
INTERNAL_IPS = ['127.0.0.1']
|
|
16
13
|
|
|
17
14
|
META_USE_SITES = True
|
|
18
15
|
META_SITE_PROTOCOL = 'https'
|
|
@@ -50,12 +47,8 @@ INSTALLED_APPS = [
|
|
|
50
47
|
'treebeard', # Tree structure of pages and plugins.
|
|
51
48
|
'sekizai', # Static file management.
|
|
52
49
|
|
|
53
|
-
'djangocms_text',
|
|
54
|
-
'djangocms_link',
|
|
55
|
-
'djangocms_alias',
|
|
56
|
-
'djangocms_versioning',
|
|
57
|
-
|
|
58
50
|
# Other Django CMS's useful modules.
|
|
51
|
+
'djangocms_text_ckeditor',
|
|
59
52
|
'djangocms_googlemap',
|
|
60
53
|
|
|
61
54
|
# Django Filer's modules.
|
|
@@ -77,13 +70,11 @@ INSTALLED_APPS = [
|
|
|
77
70
|
'djangocms_frontend.contrib.collapse',
|
|
78
71
|
'djangocms_frontend.contrib.content',
|
|
79
72
|
'djangocms_frontend.contrib.grid',
|
|
80
|
-
'djangocms_frontend.contrib.icon',
|
|
81
|
-
'djangocms_frontend.contrib.image',
|
|
82
73
|
'djangocms_frontend.contrib.jumbotron',
|
|
83
74
|
'djangocms_frontend.contrib.link',
|
|
84
75
|
'djangocms_frontend.contrib.listgroup',
|
|
85
76
|
'djangocms_frontend.contrib.media',
|
|
86
|
-
'djangocms_frontend.contrib.
|
|
77
|
+
'djangocms_frontend.contrib.image',
|
|
87
78
|
'djangocms_frontend.contrib.tabs',
|
|
88
79
|
'djangocms_frontend.contrib.utilities',
|
|
89
80
|
|
|
@@ -92,6 +83,7 @@ INSTALLED_APPS = [
|
|
|
92
83
|
'constance',
|
|
93
84
|
'constance.backends.database',
|
|
94
85
|
'import_export',
|
|
86
|
+
'mailqueue',
|
|
95
87
|
|
|
96
88
|
# Aldryn forms
|
|
97
89
|
'aldryn_forms',
|
cms_qe/settings/base/cache.py
CHANGED
|
@@ -5,11 +5,9 @@ Caching setting by default in-memory without need to configure anything.
|
|
|
5
5
|
# Caching
|
|
6
6
|
# https://docs.djangoproject.com/en/4.2/topics/cache/
|
|
7
7
|
|
|
8
|
-
# https://pypi.org/project/python-environ/
|
|
9
|
-
# Supported types / cache_url
|
|
10
|
-
|
|
11
|
-
from .env import ENV
|
|
12
|
-
|
|
13
8
|
CACHES = {
|
|
14
|
-
|
|
9
|
+
'default': {
|
|
10
|
+
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
|
|
11
|
+
'LOCATION': '127.0.0.1:11211',
|
|
12
|
+
}
|
|
15
13
|
}
|
cms_qe/settings/base/cms.py
CHANGED
|
@@ -41,7 +41,7 @@ THUMBNAIL_PROCESSORS = (
|
|
|
41
41
|
'easy_thumbnails.processors.filters'
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
TEXT_ADDITIONAL_TAGS = ('iframe',)
|
|
45
45
|
|
|
46
46
|
# cmsplugin_filer_folder
|
|
47
47
|
CMSPLUGIN_FILER_FOLDER_STYLE_CHOICES = (
|
|
@@ -65,6 +65,3 @@ DJANGOCMS_FRONTEND_GRID_CONTAINERS = (
|
|
|
65
65
|
("container-full", _("Full container")),
|
|
66
66
|
(" ", "----"),
|
|
67
67
|
)
|
|
68
|
-
|
|
69
|
-
# For example: ["css/bootstrap.min.css", "css/screen.css"]
|
|
70
|
-
STYLES_FOR_ALIAS_ADMIN_PREVIEW: list[str] = []
|
|
@@ -139,6 +139,14 @@ MAILCHIMP_CONSTANCE_CONFIG = (
|
|
|
139
139
|
)),
|
|
140
140
|
)
|
|
141
141
|
|
|
142
|
+
REDIRECT_TO_PAGE = (
|
|
143
|
+
('REDIRECT_TO_PAGE', (
|
|
144
|
+
'',
|
|
145
|
+
mark_safe('<div>Redirect to page from path <code>/redirect-to-page/</code>.</div>'
|
|
146
|
+
'<div>Example: <pre>/path/one/\n/path/two/ localhost:8000</pre></div>'),
|
|
147
|
+
)),
|
|
148
|
+
)
|
|
149
|
+
|
|
142
150
|
# The content ready for .well-known/security.txt
|
|
143
151
|
SECURITY_TXT_CONTENT = None # "Contact: mailto:abuse@nic.cz"
|
|
144
152
|
|
|
@@ -156,12 +164,14 @@ SECURITY_TXT_CONFIG = (
|
|
|
156
164
|
]),
|
|
157
165
|
)
|
|
158
166
|
|
|
167
|
+
|
|
159
168
|
CONSTANCE_CONFIG = OrderedDict(
|
|
160
169
|
GOOGLE_ANALYTICS_CONSTANCE_CONFIG + # type: ignore
|
|
161
170
|
GOOGLE_TAG_MANAGER_CONSTANCE_CONFIG + # type: ignore
|
|
162
171
|
PIWIK_CONSTANCE_CONFIG + # type: ignore
|
|
163
172
|
DJANGOCMS_GOOGLEMAP_CONSTANCE_CONFIG + # type: ignore
|
|
164
173
|
MAILCHIMP_CONSTANCE_CONFIG + # type: ignore
|
|
174
|
+
REDIRECT_TO_PAGE + # type: ignore
|
|
165
175
|
SECURITY_TXT_CONFIG # type: ignore
|
|
166
176
|
)
|
|
167
177
|
|
|
@@ -171,6 +181,7 @@ CONSTANCE_CONFIG_FIELDSETS = {
|
|
|
171
181
|
'Google tag manager options': dict(GOOGLE_TAG_MANAGER_CONSTANCE_CONFIG).keys(),
|
|
172
182
|
'Piwik options': dict(PIWIK_CONSTANCE_CONFIG).keys(),
|
|
173
183
|
'Mailchimp options': dict(MAILCHIMP_CONSTANCE_CONFIG).keys(),
|
|
184
|
+
'Redirect to page': dict(REDIRECT_TO_PAGE).keys(),
|
|
174
185
|
'Security.txt': dict(SECURITY_TXT_CONFIG).keys(),
|
|
175
186
|
}
|
|
176
187
|
|
cms_qe/settings/base/database.py
CHANGED
|
@@ -5,12 +5,15 @@ Database settings, used PostgreSQL without auth by default.
|
|
|
5
5
|
# Database
|
|
6
6
|
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
|
|
7
7
|
|
|
8
|
-
# https://pypi.org/project/python-environ/
|
|
9
|
-
# Supported types / db_url
|
|
10
|
-
|
|
11
|
-
from .env import ENV
|
|
12
|
-
|
|
13
|
-
# Database
|
|
14
8
|
DATABASES = {
|
|
15
|
-
|
|
9
|
+
'default': {
|
|
10
|
+
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
11
|
+
'NAME': 'cms_qe',
|
|
12
|
+
'USER': '',
|
|
13
|
+
'PASSWORD': '',
|
|
14
|
+
'HOST': '',
|
|
15
|
+
'OPTIONS': {
|
|
16
|
+
'application_name': 'cms_qe',
|
|
17
|
+
}
|
|
18
|
+
}
|
|
16
19
|
}
|
cms_qe/settings/base/email.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Mailing settings, by default app looks for smtp server.
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
|
|
5
|
+
EMAIL_HOST = 'localhost'
|
|
6
|
+
EMAIL_PORT = 587 # TLS uses usually 587, not 22
|
|
7
|
+
|
|
8
|
+
EMAIL_HOST_USER = ''
|
|
9
|
+
EMAIL_HOST_PASSWORD = ''
|
|
10
|
+
|
|
11
|
+
EMAIL_USE_TLS = True # Prefer to use secure mailing by default
|
|
12
|
+
EMAIL_SUBJECT_PREFIX = '' # Remove Django default prefix
|
|
13
|
+
|
|
14
|
+
DEFAULT_FROM_EMAIL = 'django_cms_qe@localhost'
|
cms_qe/settings/base/logging.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Logging settings with base formatters and handlers.
|
|
3
3
|
"""
|
|
4
|
-
from .env import ENV
|
|
5
4
|
|
|
6
5
|
# Logging
|
|
7
6
|
# https://docs.djangoproject.com/en/1.11/topics/logging/
|
|
@@ -50,7 +49,7 @@ LOGGING = {
|
|
|
50
49
|
'propagate': True,
|
|
51
50
|
},
|
|
52
51
|
'': {
|
|
53
|
-
'level':
|
|
52
|
+
'level': 'INFO',
|
|
54
53
|
'handlers': ['console'],
|
|
55
54
|
},
|
|
56
55
|
}
|
cms_qe/settings/base/search.py
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
-
from .env import ENV
|
|
5
|
-
|
|
6
4
|
site_resolver = Path(__file__).resolve()
|
|
7
5
|
|
|
8
6
|
PROJECT_DIR = site_resolver.parent.parent.parent.parent
|
|
9
7
|
|
|
10
8
|
HAYSTACK_ROUTERS = ['aldryn_search.router.LanguageRouter']
|
|
11
9
|
HAYSTACK_ENGINE = 'cms_qe.whoosh.backend.AnalyzerWhooshEngine'
|
|
12
|
-
_HAYSTACK_PATH =
|
|
10
|
+
_HAYSTACK_PATH = os.path.normpath(os.path.join(PROJECT_DIR, 'whoosh_index'))
|
|
13
11
|
HAYSTACK_CONNECTIONS = {
|
|
14
12
|
'default': {'ENGINE': HAYSTACK_ENGINE, 'PATH': os.path.join(_HAYSTACK_PATH, 'default')},
|
|
15
13
|
'en': {'ENGINE': HAYSTACK_ENGINE, 'PATH': os.path.join(_HAYSTACK_PATH, 'en')},
|
|
16
14
|
}
|
|
17
15
|
HAYSTACK_CUSTOM_HIGHLIGHTER = "cms_qe.haystack.highlighting.HaystackHighlighter"
|
|
18
|
-
|
|
19
|
-
ALDRYN_NEWSBLOG_UPDATE_SEARCH_DATA_ON_SAVE = True
|
cms_qe/settings/base/security.py
CHANGED
|
@@ -41,11 +41,10 @@ authorization by one of those options (more about that in `documentation
|
|
|
41
41
|
AXES_NUM_PROXIES = 1
|
|
42
42
|
|
|
43
43
|
"""
|
|
44
|
-
from .env import ENV
|
|
45
44
|
|
|
46
45
|
# Cookies.
|
|
47
46
|
|
|
48
|
-
SESSION_COOKIE_NAME =
|
|
47
|
+
SESSION_COOKIE_NAME = 'sessionid'
|
|
49
48
|
SESSION_COOKIE_SECURE = True
|
|
50
49
|
|
|
51
50
|
# Secure headers.
|
cms_qe/settings/dev.py
CHANGED
|
@@ -8,7 +8,6 @@ import os
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
from .base import * # noqa: F401,F403 pylint: disable=wildcard-import,unused-wildcard-import
|
|
11
|
-
from .base.env import ENV
|
|
12
11
|
|
|
13
12
|
# Quick-start development settings - unsuitable for production
|
|
14
13
|
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
|
|
@@ -17,7 +16,7 @@ DEBUG = True
|
|
|
17
16
|
|
|
18
17
|
META_SITE_PROTOCOL = 'http'
|
|
19
18
|
|
|
20
|
-
SECRET_KEY =
|
|
19
|
+
SECRET_KEY = '^xzhq0*q1+t0*ihq^^1wuyj3i%y#(38b7d-vlpkm-d(=!^uk6x'
|
|
21
20
|
|
|
22
21
|
SESSION_COOKIE_SECURE = False
|
|
23
22
|
|
|
@@ -39,35 +38,30 @@ MIDDLEWARE += [ # noqa: F405
|
|
|
39
38
|
site_resolver = Path(__file__).resolve()
|
|
40
39
|
|
|
41
40
|
PROJECT_DIR = site_resolver.parent.parent.parent
|
|
42
|
-
RUN_SITE_DIR = os.environ.get("VENV_PATH", PROJECT_DIR)
|
|
43
41
|
|
|
44
|
-
STATIC_ROOT =
|
|
45
|
-
MEDIA_ROOT = ENV.str("MEDIA_ROOT", default=os.path.join(RUN_SITE_DIR, 'media'))
|
|
42
|
+
STATIC_ROOT = os.path.join(PROJECT_DIR, 'staticfiles')
|
|
46
43
|
|
|
47
44
|
# Caching
|
|
45
|
+
# https://docs.djangoproject.com/en/1.11/topics/cache/
|
|
46
|
+
|
|
48
47
|
CACHES = {
|
|
49
|
-
|
|
48
|
+
'default': {
|
|
49
|
+
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
|
|
50
|
+
'LOCATION': os.path.join(PROJECT_DIR, 'django_cache'),
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
# Database
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
DATABASES = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
REST_FRAMEWORK = {
|
|
65
|
-
'EXCEPTION_HANDLER': 'cms_qe.api.utils.exception_handler',
|
|
66
|
-
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
|
55
|
+
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
|
|
56
|
+
|
|
57
|
+
DATABASES = {
|
|
58
|
+
'default': {
|
|
59
|
+
'ENGINE': 'django.db.backends.sqlite3',
|
|
60
|
+
'NAME': os.path.join(PROJECT_DIR, 'db.sqlite3'),
|
|
61
|
+
'TEST': {
|
|
62
|
+
'NAME': ':memory:',
|
|
63
|
+
},
|
|
64
|
+
}
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
API_VIEWS = [
|
|
71
|
-
('aldryn-forms/forms', 'aldryn_forms.api.views.FormViewSet', 'aldryn-forms-form'),
|
|
72
|
-
('aldryn-forms/submitssions', 'aldryn_forms.api.views.SubmissionsViewSet', 'aldryn-forms-submitssions'),
|
|
73
|
-
]
|
|
67
|
+
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
cms_qe/templates/base.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% load i18n static cms_tags
|
|
1
|
+
{% load i18n static cms_tags sekizai_tags %}
|
|
2
2
|
{# Doctype is important for Django CMS so it can correctly detect height of window. #}
|
|
3
3
|
<!DOCTYPE html>
|
|
4
4
|
<html lang="{{ LANGUAGE_CODE }}">
|
|
@@ -9,20 +9,17 @@
|
|
|
9
9
|
{% include 'cms_qe/include/head.html' %}
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
|
-
{% cms_toolbar %}
|
|
13
|
-
{% block menu %}
|
|
14
|
-
<menu>{% show_menu 0 100 100 100 %}</menu>
|
|
15
|
-
{% endblock %}
|
|
16
12
|
{% include 'cms_qe/include/body_top.html' %}
|
|
13
|
+
{% cms_toolbar %}
|
|
17
14
|
{% block header %}
|
|
18
15
|
<header>
|
|
19
|
-
{%
|
|
16
|
+
{% static_placeholder "header" %}
|
|
20
17
|
</header>
|
|
21
18
|
{% endblock %}
|
|
22
19
|
{% block content %}{% endblock %}
|
|
23
20
|
{% block footers %}
|
|
24
21
|
<footer>
|
|
25
|
-
{%
|
|
22
|
+
{% static_placeholder "footer" %}
|
|
26
23
|
</footer>
|
|
27
24
|
{% endblock %}
|
|
28
25
|
{% include "cms_qe/include/body_bottom.html" %}
|
cms_qe/utils.py
CHANGED
|
@@ -5,35 +5,41 @@ from typing import Optional, Union
|
|
|
5
5
|
from django.apps import apps
|
|
6
6
|
from django.conf import settings
|
|
7
7
|
from django.contrib.sites.shortcuts import get_current_site
|
|
8
|
-
from django.core.mail import EmailMultiAlternatives
|
|
9
8
|
from django.template import TemplateDoesNotExist
|
|
10
9
|
from django.template.loader import get_template
|
|
10
|
+
from mailqueue.models import MailerMessage
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
# pylint:disable=invalid-name
|
|
14
14
|
def get_email(template: str, subject: str, to: Union[str, Iterable[str]], from_email: Optional[str] = None, **kwargs):
|
|
15
15
|
"""
|
|
16
|
-
Returns a ``
|
|
16
|
+
Returns a ``MailerMessage`` instance from ``mailqueue``. Use ``save()`` method instead of ``send()`` to send
|
|
17
|
+
message or put it to a mailqueue.
|
|
17
18
|
|
|
18
19
|
Template should be without extension and you should create both ``.txt`` and ``.html`` version.
|
|
19
20
|
Second one is not mandatory but is good to provide it as well.
|
|
20
21
|
|
|
21
22
|
"""
|
|
23
|
+
|
|
24
|
+
email = MailerMessage()
|
|
25
|
+
email.subject = subject
|
|
26
|
+
email.from_address = from_email or settings.DEFAULT_FROM_EMAIL
|
|
27
|
+
|
|
28
|
+
if isinstance(to, str):
|
|
29
|
+
to = [to]
|
|
30
|
+
email.to_address = ', '.join(to)
|
|
31
|
+
|
|
22
32
|
template_txt = get_template(template + '.txt')
|
|
33
|
+
content = template_txt.render(kwargs)
|
|
34
|
+
email.content = content
|
|
23
35
|
|
|
24
|
-
msg = EmailMultiAlternatives(
|
|
25
|
-
subject,
|
|
26
|
-
template_txt.render(kwargs),
|
|
27
|
-
from_email or settings.DEFAULT_FROM_EMAIL,
|
|
28
|
-
[to] if isinstance(to, str) else to,
|
|
29
|
-
)
|
|
30
36
|
try:
|
|
31
37
|
template_html = get_template(template + '.html')
|
|
32
|
-
msg.attach_alternative(template_html.render(kwargs), "text/html")
|
|
33
38
|
except TemplateDoesNotExist:
|
|
34
|
-
|
|
39
|
+
return email
|
|
40
|
+
email.html_content = template_html.render(kwargs)
|
|
35
41
|
|
|
36
|
-
return
|
|
42
|
+
return email
|
|
37
43
|
|
|
38
44
|
|
|
39
45
|
def get_base_url(request) -> str:
|
cms_qe/views/redirect_to_page.py
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
|
-
"""
|
|
2
|
-
from django.utils.safestring import mark_safe
|
|
3
|
-
|
|
4
|
-
REDIRECT_TO_PAGE = (
|
|
5
|
-
('REDIRECT_TO_PAGE', (
|
|
6
|
-
'',
|
|
7
|
-
mark_safe('Redirect to page. Example: <pre>/path/one/\n/path/two/ localhost:8000</pre>'),
|
|
8
|
-
)),
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
EXTRA_CONSTANCE_CONFIG = ... + REDIRECT_TO_PAGE
|
|
12
|
-
"""
|
|
13
1
|
import re
|
|
2
|
+
|
|
3
|
+
from constance import config
|
|
14
4
|
from django.views.generic import RedirectView
|
|
15
5
|
|
|
16
6
|
|
|
@@ -19,20 +9,19 @@ class RedirectToPage(RedirectView):
|
|
|
19
9
|
|
|
20
10
|
url = "/"
|
|
21
11
|
|
|
12
|
+
def get_from_host(self):
|
|
13
|
+
return self.request.GET.get("fromhost")
|
|
14
|
+
|
|
22
15
|
def get_redirect_url(self, *args, **kwargs):
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
redirect_to_page = config.REDIRECT_TO_PAGE
|
|
26
|
-
except (ModuleNotFoundError, AttributeError):
|
|
27
|
-
return self.url
|
|
28
|
-
for line in re.split("\n+", redirect_to_page):
|
|
16
|
+
from_host = self.get_from_host()
|
|
17
|
+
for line in re.split("\n+", config.REDIRECT_TO_PAGE):
|
|
29
18
|
line = line.strip()
|
|
30
19
|
groups = re.match(r"(?P<path>\S+)(\s+(?P<host>\S+))?", line.strip())
|
|
31
20
|
if groups is None:
|
|
32
21
|
continue
|
|
33
22
|
if groups['host'] is None:
|
|
34
23
|
return groups['path']
|
|
35
|
-
if groups['host'] ==
|
|
24
|
+
if groups['host'] == from_host:
|
|
36
25
|
return groups['path']
|
|
37
26
|
continue
|
|
38
27
|
return self.url
|
cms_qe_auth/models.py
CHANGED
cms_qe_test/cms.py
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
from cms import api
|
|
2
|
-
from cms.models import
|
|
2
|
+
from cms.models import Placeholder
|
|
3
3
|
from cms.plugin_rendering import ContentRenderer
|
|
4
|
-
from cms.toolbar.toolbar import CMSToolbar
|
|
5
|
-
from django.contrib.auth import get_user_model
|
|
6
4
|
from django.contrib.auth.models import AnonymousUser
|
|
7
5
|
from django.contrib.messages.storage.fallback import FallbackStorage
|
|
8
6
|
from django.test import RequestFactory
|
|
9
|
-
from djangocms_versioning.constants import DRAFT, PUBLISHED
|
|
10
|
-
from djangocms_versioning.models import Version
|
|
11
7
|
from sekizai.context import SekizaiContext
|
|
12
8
|
|
|
13
9
|
|
|
@@ -15,7 +11,6 @@ def render_plugin(plugin, path='/', **data):
|
|
|
15
11
|
placeholder = Placeholder.objects.create(slot='test')
|
|
16
12
|
model_instance = api.add_plugin(placeholder, plugin, 'en', **data)
|
|
17
13
|
request = generate_get_request(path)
|
|
18
|
-
request.toolbar = CMSToolbar(request)
|
|
19
14
|
renderer = ContentRenderer(request=request)
|
|
20
15
|
context = SekizaiContext()
|
|
21
16
|
context.update({'request': request, })
|
|
@@ -40,28 +35,16 @@ def generate_post_request(path='', body=None):
|
|
|
40
35
|
|
|
41
36
|
|
|
42
37
|
# pylint: disable=dangerous-default-value
|
|
43
|
-
def create_page(title, language='en', page_params={}
|
|
38
|
+
def create_page(title, language='en', page_params={}):
|
|
39
|
+
page_params.setdefault('published', True)
|
|
44
40
|
page_params.setdefault('overwrite_url', page_params.get('slug'))
|
|
45
|
-
|
|
46
|
-
content = PageContent.admin_manager.get(page=page)
|
|
47
|
-
user, _ = get_user_model().objects.get_or_create(username="tester")
|
|
48
|
-
version = content.versions.last()
|
|
49
|
-
if version is None:
|
|
50
|
-
version_state = PUBLISHED if state == "publish" else DRAFT
|
|
51
|
-
Version.objects.create(content=content, created_by=user, state=version_state)
|
|
52
|
-
else:
|
|
53
|
-
getattr(version, state)(user) # version.publish(user) / version.unpublish(user)
|
|
54
|
-
return page
|
|
41
|
+
return api.create_page(title, 'cms_qe/home.html', language, **page_params)
|
|
55
42
|
|
|
56
43
|
|
|
57
44
|
# pylint: disable=dangerous-default-value
|
|
58
45
|
def create_text_page(title, language='en', page_params={}, plugin_params={}):
|
|
59
46
|
plugin_params.setdefault('body', 'shello')
|
|
60
47
|
page = create_page(title, language, page_params)
|
|
61
|
-
placeholder = page.
|
|
48
|
+
placeholder = page.placeholders.get(slot='content')
|
|
62
49
|
api.add_plugin(placeholder, 'TextPlugin', language, **plugin_params)
|
|
63
50
|
return page
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def create_draft_page(title, language='en', page_params={}, state="unpublish"):
|
|
67
|
-
return create_page(title, language, page_params=page_params, state=state)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-cms-qe
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.2
|
|
4
4
|
Summary: Django CMS Quick & Easy provides all important modules to run new page withouta lot of coding. Aims to do it very easily and securely.
|
|
5
5
|
Home-page: https://websites.pages.nic.cz/django-cms-qe
|
|
6
6
|
Author: CZ.NIC, z.s.p.o.
|
|
@@ -23,41 +23,36 @@ Classifier: Framework :: Django :: 4.0
|
|
|
23
23
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
24
24
|
Classifier: Topic :: Software Development
|
|
25
25
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
26
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Requires-Dist: django
|
|
30
|
-
Requires-Dist: django-
|
|
31
|
-
Requires-Dist: djangocms-admin-style~=3.3
|
|
32
|
-
Requires-Dist: djangocms-alias~=2.0
|
|
33
|
-
Requires-Dist: djangocms-frontend~=2.1
|
|
34
|
-
Requires-Dist: djangocms-text~=0.8
|
|
35
|
-
Requires-Dist: djangocms-versioning~=2.3
|
|
29
|
+
Requires-Dist: django~=4.2
|
|
30
|
+
Requires-Dist: django-cms~=3.11
|
|
36
31
|
Requires-Dist: easy-thumbnails[svg]~=2.10
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: django-
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: django-
|
|
41
|
-
Requires-Dist: django-
|
|
42
|
-
Requires-Dist: django-tablib~=3.2
|
|
32
|
+
Requires-Dist: djangocms-frontend~=1.1
|
|
33
|
+
Requires-Dist: django-csp~=3.7
|
|
34
|
+
Requires-Dist: djangocms-picture~=4.0
|
|
35
|
+
Requires-Dist: django-axes~=6.0
|
|
36
|
+
Requires-Dist: django-constance[database]~=2.9
|
|
43
37
|
Requires-Dist: djangocms-file~=3.0
|
|
44
|
-
Requires-Dist:
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist: djangocms-
|
|
47
|
-
Requires-Dist: djangocms-
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist: django-haystack~=3.3
|
|
50
|
-
Requires-Dist: djangocms-aldryn-forms[captcha]~=8.0
|
|
51
|
-
Requires-Dist: djangocms-aldryn-search~=3.0
|
|
38
|
+
Requires-Dist: django-import-export~=3.2
|
|
39
|
+
Requires-Dist: django-mail-queue==3.2.5
|
|
40
|
+
Requires-Dist: djangocms-icon~=2.0
|
|
41
|
+
Requires-Dist: djangocms-googlemap~=2.0
|
|
42
|
+
Requires-Dist: django-tablib~=3.2
|
|
52
43
|
Requires-Dist: mailchimp3~=3.0
|
|
44
|
+
Requires-Dist: argon2-cffi~=21.3
|
|
45
|
+
Requires-Dist: djangocms-aldryn-forms[captcha]~=7.7
|
|
46
|
+
Requires-Dist: djangocms-aldryn-search~=2.0
|
|
47
|
+
Requires-Dist: django-haystack~=3.2
|
|
48
|
+
Requires-Dist: pymemcache~=4.0
|
|
53
49
|
Requires-Dist: whoosh~=2.7
|
|
54
|
-
Requires-Dist:
|
|
50
|
+
Requires-Dist: djangorestframework~=3.16
|
|
51
|
+
Requires-Dist: markdown~=3.8
|
|
55
52
|
Requires-Dist: django-filter~=25.1
|
|
56
53
|
Requires-Dist: django-rest-knox~=5.0
|
|
57
|
-
Requires-Dist: djangorestframework~=3.16
|
|
58
54
|
Requires-Dist: drf-spectacular~=0.28
|
|
59
55
|
Provides-Extra: dev
|
|
60
|
-
Requires-Dist: django-simple-captcha~=0.5; extra == "dev"
|
|
61
56
|
Requires-Dist: django-debug-toolbar~=4.1; extra == "dev"
|
|
62
57
|
Requires-Dist: django-extensions~=3.2; extra == "dev"
|
|
63
58
|
Provides-Extra: test
|
|
@@ -67,7 +62,6 @@ Requires-Dist: mypy; extra == "test"
|
|
|
67
62
|
Requires-Dist: pylint; extra == "test"
|
|
68
63
|
Requires-Dist: pylint-django; extra == "test"
|
|
69
64
|
Requires-Dist: pytest~=6.2; extra == "test"
|
|
70
|
-
Requires-Dist: pytest-cov~=6.2; extra == "test"
|
|
71
65
|
Requires-Dist: pytest-data~=0.4; extra == "test"
|
|
72
66
|
Requires-Dist: pytest-django~=3.9; extra == "test"
|
|
73
67
|
Requires-Dist: pytest-env~=0.6; extra == "test"
|
|
@@ -87,7 +81,7 @@ Requires-Dist: psycopg2; extra == "psql"
|
|
|
87
81
|
Provides-Extra: mysql
|
|
88
82
|
Requires-Dist: mysqlclient~=2.2; extra == "mysql"
|
|
89
83
|
Provides-Extra: newsblog
|
|
90
|
-
Requires-Dist: djangocms-aldryn-newsblog~=
|
|
84
|
+
Requires-Dist: djangocms-aldryn-newsblog~=3.3; extra == "newsblog"
|
|
91
85
|
Dynamic: author
|
|
92
86
|
Dynamic: author-email
|
|
93
87
|
Dynamic: classifier
|
|
@@ -150,36 +144,3 @@ To find more useful commands, run just `make`.
|
|
|
150
144
|
## Upgrade
|
|
151
145
|
|
|
152
146
|
To upgrade from version `2.2` to version >= `3.0.0`, you can use the [DjangoCMS upgrade plugins](https://gitlab.nic.cz/utils/djangocms-upgrade-plugins) tool.
|
|
153
|
-
|
|
154
|
-
## Example in Docker
|
|
155
|
-
|
|
156
|
-
Download example:
|
|
157
|
-
|
|
158
|
-
curl https://gitlab.nic.cz/websites/django-cms-qe/-/archive/master/django-cms-qe.zip?path=example --output example.zip
|
|
159
|
-
|
|
160
|
-
Unzip and go to the example folder:
|
|
161
|
-
|
|
162
|
-
unzip example.zip
|
|
163
|
-
cd django-cms-qe*/example/
|
|
164
|
-
|
|
165
|
-
Build the site image:
|
|
166
|
-
|
|
167
|
-
docker compose build
|
|
168
|
-
|
|
169
|
-
Run website in docker:
|
|
170
|
-
|
|
171
|
-
docker compose up -d
|
|
172
|
-
|
|
173
|
-
See the website at http://localhost:8000/. Login into http://localhost:8000/admin/ as username ``admin`` with password ``admin``.
|
|
174
|
-
To run on a different port, specify the PORT parameter:
|
|
175
|
-
|
|
176
|
-
PORT=8008 docker compose up -d
|
|
177
|
-
|
|
178
|
-
Please wait a moment before browsing the website. It takes a while for all migrations to be completed and data to be loaded.
|
|
179
|
-
You can monitor the status of this process in the log:
|
|
180
|
-
|
|
181
|
-
docker compose logs -f web
|
|
182
|
-
|
|
183
|
-
Stop the website:
|
|
184
|
-
|
|
185
|
-
docker compose down
|
|
@@ -2,15 +2,13 @@ cms_qe/__init__.py,sha256=do1c4s8BgjukMZMMMhBHs_lG9j8ncnAjR3oTICWEq5w,684
|
|
|
2
2
|
cms_qe/admin.py,sha256=eLqAF3UIDWWyA0xE0Ft5WP5_3HImSWk3EYL2cRfL_8A,171
|
|
3
3
|
cms_qe/apps.py,sha256=AeRcBWwGs7rKLlzHhnV8M_2BEnkoO9959VwesxfHaio,338
|
|
4
4
|
cms_qe/constants.py,sha256=YWUWCIabSwcamGZynvkJ9i8OWGtfHf-wFirm8GtqQpI,90
|
|
5
|
-
cms_qe/export.py,sha256=
|
|
5
|
+
cms_qe/export.py,sha256=PyKzMoFGzMdwCTKIYP1zri0Pn8zR_2e0-IkbHYfAv3g,8138
|
|
6
6
|
cms_qe/fixtures.py,sha256=cq_wnZnqBwPBOHpp_0bHk424iCXKvwmN6ZaKwDvguXk,755
|
|
7
|
-
cms_qe/hooks.py,sha256=L9gLppl74Gj8euTJ1vWuSlc553ZAFAkj6mZaGw7iaW8,3330
|
|
8
|
-
cms_qe/ldap.py,sha256=2mpFdLoIdT_pAiGJ6ADnE74YXjaC55aNANv0L8DVwqU,188
|
|
9
7
|
cms_qe/monitoring.py,sha256=5t_o7o0htmAAxVjkN2oz0O0v9XdzfePhSfPGcLNPmE8,769
|
|
10
8
|
cms_qe/signals.py,sha256=MbuLSxPlJA147LEg-lDWDoUNTV1y0OKjwoI3HzgR97g,1253
|
|
11
9
|
cms_qe/staticfiles.py,sha256=OHkfDfpIxN0B-eCRagZzHDHyBgaulcyYgKhp_3mPZuk,1363
|
|
12
10
|
cms_qe/urls.py,sha256=npDzzW9SgLVMZECTyOUL5Cpw7RxeuuNssTKOXuXuxtM,3247
|
|
13
|
-
cms_qe/utils.py,sha256=
|
|
11
|
+
cms_qe/utils.py,sha256=gxsWZmS34ZC0Tv1VW8A7VeGlrPyDshodF1ZWXj7xyWE,3057
|
|
14
12
|
cms_qe/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
13
|
cms_qe/api/constants.py,sha256=pdSziATRm6yUaaPBYoD07JXcULMvKD0h5RdNTPpG0rM,64
|
|
16
14
|
cms_qe/api/permissions.py,sha256=QKSll8wVOWKNbvX_FsC9CRKbPVcT2s5FM81_fnqeEQg,409
|
|
@@ -35,7 +33,7 @@ cms_qe/boilerplates/bootstrap3/static/cms_qe/js/bootstrap.min.js,sha256=U5ZEeKfG
|
|
|
35
33
|
cms_qe/boilerplates/bootstrap3/static/cms_qe/js/jquery_3.2.1.min.js,sha256=hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4,86659
|
|
36
34
|
cms_qe/boilerplates/bootstrap3/static/cms_qe/js/npm.js,sha256=x6qCoap9RSJKONkm0q2v9_5K71vNr6Kke9rAV_RCLC0,484
|
|
37
35
|
cms_qe/boilerplates/bootstrap3/templates/cms_qe/error.html,sha256=gHFQbT2KPAwnhos6uMk4gvijDjubwiOA-j_q9fASBZM,375
|
|
38
|
-
cms_qe/boilerplates/bootstrap3/templates/cms_qe/home.html,sha256=
|
|
36
|
+
cms_qe/boilerplates/bootstrap3/templates/cms_qe/home.html,sha256=swbpKbL2KJhDdnuLRUelfQn7xPxolzYye4fLrLjFVOM,1465
|
|
39
37
|
cms_qe/boilerplates/bootstrap3/templates/cmsplugin_filer_folder/plugins/folder/gallery.html,sha256=ZAbkXcsJ6mwAJt0vQNd55ZWB-BhJ_gtvtbnKx8PysV8,3107
|
|
40
38
|
cms_qe/haystack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
39
|
cms_qe/haystack/forms.py,sha256=4FyieMfxfE6h2dcUaWAZJ18rEOAcnMVb2zLZ60iCbVA,912
|
|
@@ -54,31 +52,26 @@ cms_qe/middleware/page_status_code.py,sha256=J-Ezet9ban9rnjWaSuRss9gOz5h7uCCyL46
|
|
|
54
52
|
cms_qe/migrations/0001_api_permissions.py,sha256=KPJYBdX3dWYEbUswSiIhkhDV6FcjXG-MPfC2aYwt7Wc,672
|
|
55
53
|
cms_qe/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
54
|
cms_qe/settings/__init__.py,sha256=GJwHXMHwMuGYE-3ZzePJ-26I2WwE8bAIMUDoiTFr0L8,982
|
|
57
|
-
cms_qe/settings/dev.py,sha256=
|
|
55
|
+
cms_qe/settings/dev.py,sha256=51CBwiclE8LLoNB2uioIK_L3JhM1yzukQ0gZimkcFqw,1487
|
|
58
56
|
cms_qe/settings/unittest.py,sha256=folLIMJb1Arh60_Sn0eNQrvIlx0OsAs6v1tDfyRZVuQ,514
|
|
59
57
|
cms_qe/settings/base/__init__.py,sha256=5yHfne9gPD_xuTaG3voZP23yzuCwROmif2mmKs-hG_A,446
|
|
60
|
-
cms_qe/settings/base/app.py,sha256=
|
|
58
|
+
cms_qe/settings/base/app.py,sha256=RGxe4deN_qLGc_aRNKGjmBgsWYYpd-wdm6V47a0VR5I,4213
|
|
61
59
|
cms_qe/settings/base/auth.py,sha256=OTr1LJ4RSMZm8STs4Q3pwPXmQoURax8OKLJ8eAj7PW4,395
|
|
62
|
-
cms_qe/settings/base/cache.py,sha256=
|
|
63
|
-
cms_qe/settings/base/cms.py,sha256=
|
|
64
|
-
cms_qe/settings/base/constants.py,sha256=
|
|
65
|
-
cms_qe/settings/base/database.py,sha256=
|
|
66
|
-
cms_qe/settings/base/email.py,sha256=
|
|
67
|
-
cms_qe/settings/base/env.py,sha256=Oe10oSrA7QlD9TBDnEup8mtNTd1pXyaO5OThtUW8UVQ,36
|
|
60
|
+
cms_qe/settings/base/cache.py,sha256=9p6C5lOz1pG-6k15PyvxlShUjBYIbU0ewpA8AX_YFus,297
|
|
61
|
+
cms_qe/settings/base/cms.py,sha256=8icCNxcEp_KRDyP8-LXB21UurJL4wNysY39whAyt3I4,1855
|
|
62
|
+
cms_qe/settings/base/constants.py,sha256=2lggnUhHesx5HKaz8kJ983JwHEPj4ZLoMfhgOqERPZY,8248
|
|
63
|
+
cms_qe/settings/base/database.py,sha256=qT7ePr2lg4CVJcHnG2nXFPPvzIjBOLB4auvRiWxaDPY,408
|
|
64
|
+
cms_qe/settings/base/email.py,sha256=agT6ZBAyT29TUEQIRYObAdgOSETLlZEi7KizNhr9dVc,357
|
|
68
65
|
cms_qe/settings/base/i18n.py,sha256=n_7esPYSbf9Wj-T23uWds7tCvQ0ol9MfyMtKzy009sM,355
|
|
69
|
-
cms_qe/settings/base/logging.py,sha256=
|
|
66
|
+
cms_qe/settings/base/logging.py,sha256=GFVyQ_DcdKl9iu9C8fCshrAdrIKY0T-OD6lst5bb8qQ,1319
|
|
70
67
|
cms_qe/settings/base/path.py,sha256=s0eOmSDOWfjjI5onp28y2S2UKwCYFRDGeoUsZla6-og,410
|
|
71
|
-
cms_qe/settings/base/search.py,sha256=
|
|
72
|
-
cms_qe/settings/base/security.py,sha256=
|
|
68
|
+
cms_qe/settings/base/search.py,sha256=xbO9OFFGLi8PZut_Ngb-27BUI6HPG0ZM4lrO1HXHW-c,618
|
|
69
|
+
cms_qe/settings/base/security.py,sha256=i6mHb8gv6XPthShL1kFLTwa_vrfoaivzqC9MXLE_YBw,4496
|
|
73
70
|
cms_qe/settings/base/template.py,sha256=bITmA7XkoqbDpefWWOBsEiPtCREzFfHkUuFvGxJVLK4,1082
|
|
74
|
-
cms_qe/
|
|
75
|
-
cms_qe/templates/base.html,sha256=Hb6MWA_IpBWlCyJ2NiPPQv0nSKOJgXSXS7y62-cHGUA,1094
|
|
76
|
-
cms_qe/templates/pg_is_in_recovery_login.html,sha256=ng0snZ-rriwFRKVvG0ZCY5QsQbod7jex2pVJ3hVonc0,116
|
|
71
|
+
cms_qe/templates/base.html,sha256=BMd8MbubDB8m1ZzBWfAfzTs4EBQn0oBQUw1GVRA4z6A,972
|
|
77
72
|
cms_qe/templates/admin/index.html,sha256=6CjuqOPQnEYXa7zwyoLyDHt-zzfBwLAf45B0F80ryZ0,1812
|
|
78
|
-
cms_qe/templates/admin/inc/extrastyle.html,sha256=vgsAzeKxV8Meu5j60vo9hMzlsKnRagkyI7icucfQpEg,105
|
|
79
|
-
cms_qe/templates/cms_qe/alias_content_preview.html,sha256=2klC7206SDOCf-sWYgeEcBiG2fIA8H2OML2fwEcewXc,956
|
|
80
73
|
cms_qe/templates/cms_qe/error.html,sha256=1wNCO-ToNoM-HBnfq0Id_W8m_epmOEYcoozRhhHth5U,322
|
|
81
|
-
cms_qe/templates/cms_qe/home.html,sha256=
|
|
74
|
+
cms_qe/templates/cms_qe/home.html,sha256=XSyChEdMnxcw-OWrm_d_3h2lmXfPyfpCpyYKH6QNG2E,186
|
|
82
75
|
cms_qe/templates/cms_qe/internal_error.html,sha256=n4JJ80KNHyhiSxGLQadCn9KmctnFABcwLU4KuZly8A4,251
|
|
83
76
|
cms_qe/templates/cms_qe/search_result.html,sha256=5XDX4nhRDkSJq_EdW95p8CuEN1Yy14OG9UC3WDz7TXI,310
|
|
84
77
|
cms_qe/templates/cms_qe/include/body_bottom.html,sha256=t-B_SA2AFPmTC5hnDANyR9O9tmH3-hzGTLoRPi9lgIY,29
|
|
@@ -96,10 +89,9 @@ cms_qe/views/__init__.py,sha256=3b5FCZ5MaqgiWglC7c5mfvP3WYLWTtNp3YpVb9BgYi8,106
|
|
|
96
89
|
cms_qe/views/errors.py,sha256=zUbCoyXy_MPsQv3UV1mgq-q2bwqPw9G4KgKU2-oue4w,3169
|
|
97
90
|
cms_qe/views/maintenance.py,sha256=Q410LCeeihRWhIJ-zzRpFSjfvA6xhgr6NJlNAoTNO2U,1658
|
|
98
91
|
cms_qe/views/monitoring.py,sha256=1r2s_jm6B6P0gEmiqjH9m3loUW3BmJivvpg6qcUOxVM,1909
|
|
99
|
-
cms_qe/views/redirect_to_page.py,sha256=
|
|
92
|
+
cms_qe/views/redirect_to_page.py,sha256=2HeGxTIKQQcfXsafdDz9F1fDHKGAbpiq1qKBKMvDL70,806
|
|
100
93
|
cms_qe/views/search_result.py,sha256=H1eMOmtONnWqBDsBvz3MartyHhh42vyi0jPoxWb0X8c,296
|
|
101
94
|
cms_qe/views/security.py,sha256=SNdJe4NSm1vuOGchVF3VqlmFDopt9xYoO-b4Y0UxkFU,1108
|
|
102
|
-
cms_qe/views/test_messages.py,sha256=ULHdXwjSmQxCxFF1hzBzpDa5MltGwyIF8DjQPb7N-7M,1281
|
|
103
95
|
cms_qe/whoosh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
104
96
|
cms_qe/whoosh/backend.py,sha256=YOVJGz3htWdcSUbYtX2a9VqywAU3EJP_EvxXHCY0QVA,5418
|
|
105
97
|
cms_qe_analytical/LICENSE.txt,sha256=ptQIrnsiWFFf2LZ60DTAO6XA7CQYFuwhX1m4kzhv5_8,1072
|
|
@@ -116,7 +108,7 @@ cms_qe_auth/cms_menus.py,sha256=UxzzuMfOJCC_EiCkV2__6R5JKV9q1WGbTEgO7yLy8rE,1675
|
|
|
116
108
|
cms_qe_auth/cms_plugins.py,sha256=USiNHaWdIJqPFUMLOjhuVam4nwOckujg1uguXNIs798,1575
|
|
117
109
|
cms_qe_auth/fixtures.py,sha256=hQO75OnBmU4NiT_GF-oW4lU50FrLDgGF-gfouYeLfRI,784
|
|
118
110
|
cms_qe_auth/forms.py,sha256=x7sdFoOrKBLTJXqESedpIh6Kc1k5zZhL4vwnmhj1gH8,1137
|
|
119
|
-
cms_qe_auth/models.py,sha256=
|
|
111
|
+
cms_qe_auth/models.py,sha256=Aro43D9y1zrS-3eKHVZEuSkchusDZAcj15B2vYcdt0Q,2713
|
|
120
112
|
cms_qe_auth/token.py,sha256=DG4Bu8AVV-d1ayL4Oc9DXNnERt1sstrll80RBGrplx0,224
|
|
121
113
|
cms_qe_auth/urls.py,sha256=RCgr9t1YonE0yR_8gXiXZIGESvQfrwVwlKhBOWmgxkw,2040
|
|
122
114
|
cms_qe_auth/utils.py,sha256=JYZUzQhUE_kycVBRBNi-fmGy5WtjIwc3_qsGxOVrNR0,2972
|
|
@@ -3949,8 +3941,7 @@ cms_qe_table/templates/cms_qe/table/table_widget.html,sha256=tsjlS5Mc_6iALFk0QIe
|
|
|
3949
3941
|
cms_qe_table/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3950
3942
|
cms_qe_table/templatetags/cms_qe_table_filters.py,sha256=eFBB2FoCcpQRAknMIJLac0ts18w8XIODbouuJlP0ty4,782
|
|
3951
3943
|
cms_qe_test/__init__.py,sha256=-Vc3K2g4JFSE2qw5AvuTGi4rwQGMOXAEycrjgFWk1BQ,121
|
|
3952
|
-
cms_qe_test/cms.py,sha256=
|
|
3953
|
-
cms_qe_test/mail_filebased_backend.py,sha256=9q3YuR-WcfhNOJc6hWclJmwRs949gzGFm6Eb3W7CjeI,645
|
|
3944
|
+
cms_qe_test/cms.py,sha256=pspLQxbnwG71PuZKtwfWDu6uVk7RYO86Od1cDXBF108,1796
|
|
3954
3945
|
cms_qe_video/__init__.py,sha256=2iOdITrw_UvFcQpFA0rhUWBCRe2qvTuDvltp5Q233cc,1070
|
|
3955
3946
|
cms_qe_video/cms_plugins.py,sha256=kqJX5eb-pYutxO-_0UnO784QpTwOb5Eudo6bW2NXaZg,3020
|
|
3956
3947
|
cms_qe_video/fixtures.py,sha256=0oGo7Ufh3XwaLaMjcGN7CFao_BetcQ6xtikNeAHdqvs,701
|
|
@@ -3969,7 +3960,14 @@ cms_qe_video/templates/cms_qe/video/video_source_file.html,sha256=QJF5fs88s9Fznp
|
|
|
3969
3960
|
cms_qe_video/templates/cms_qe/video/video_widget.html,sha256=Yumciq6bGlAYI1lYx5j9V6IF8QYrncNYygPTkXEz6Wk,925
|
|
3970
3961
|
cms_qe_video/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3971
3962
|
cms_qe_video/templatetags/cms_qe_video.py,sha256=NR_mGv91J0rEreZrQjCzaaXSrZsKvrSas12wMJ-Dg24,1168
|
|
3972
|
-
django_cms_qe-3.7.
|
|
3963
|
+
django_cms_qe-3.7.2.dist-info/licenses/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
|
|
3964
|
+
example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3965
|
+
example/urls.py,sha256=H-IJsRGFVZGw6FD9gvK-0B0dLeSOsduziHvDvcHCQZ0,399
|
|
3966
|
+
example/wsgi.py,sha256=lCKhvtFZlorSIA8qYEqc3pZ1Oflrz_Tc696MWJ62ue4,396
|
|
3967
|
+
example/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3968
|
+
example/settings/aldryn_newsblog.py,sha256=iQ5idy9rZR_N5IJzogc7R3PK3RIN7OMw7ksSIIIxPDk,276
|
|
3969
|
+
example/settings/dev.py,sha256=TGGlSzh9ZDh54Z2X5i6mz7Ja3lT_qBqw9MHX3EnMs9o,676
|
|
3970
|
+
example/settings/selenium.py,sha256=pRi8pIQIiYA0Y_yZsg7M63npHMRcUsFF7gZTr602yPY,215
|
|
3973
3971
|
test_selenium/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3974
3972
|
test_selenium/browser.py,sha256=OcfqxDa9OtL7M5CSwfIxtzToMUEhqGLvditemPeEUNo,1437
|
|
3975
3973
|
test_selenium/conftest.py,sha256=mAptaAyj7a1hbUPDRWBBs1qL0TJ8Fma7Mch6PZwgtNo,220
|
|
@@ -3983,7 +3981,7 @@ test_selenium/pages/cms/__init__.py,sha256=_qe4YZYaQbrXp7Szmmeo4TUSkXlE5Rozu8E3t
|
|
|
3983
3981
|
test_selenium/pages/cms/login.py,sha256=UPzJQcYff8NUAT4nvmfQoJQxzOJyPrJ_cKtH35NVfNg,521
|
|
3984
3982
|
test_selenium/pages/cms/page.py,sha256=YQnpZkopfVnhoyQKpRDGqjNeV6xUl-pEHjEcZ9HRiPk,489
|
|
3985
3983
|
test_selenium/pages/cms/wizard.py,sha256=yatbXH-rf1ap4O1hY0I13WikM3zkm_NrAiSK6bqENIU,545
|
|
3986
|
-
django_cms_qe-3.7.
|
|
3987
|
-
django_cms_qe-3.7.
|
|
3988
|
-
django_cms_qe-3.7.
|
|
3989
|
-
django_cms_qe-3.7.
|
|
3984
|
+
django_cms_qe-3.7.2.dist-info/METADATA,sha256=hgRfyIxLQM7jkrybpP0Mmfv3Q8p7MDmbI1o6mZhxoM8,5144
|
|
3985
|
+
django_cms_qe-3.7.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
3986
|
+
django_cms_qe-3.7.2.dist-info/top_level.txt,sha256=T4dauFwJy7FmxCy7WoQI3pPwiDessNB2LkfOAP76ssE,172
|
|
3987
|
+
django_cms_qe-3.7.2.dist-info/RECORD,,
|
example/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from .dev import *
|
|
2
|
+
|
|
3
|
+
INSTALLED_APPS += [ # noqa: F405
|
|
4
|
+
# Aldryn News&Blog
|
|
5
|
+
'aldryn_apphooks_config',
|
|
6
|
+
'aldryn_common',
|
|
7
|
+
'aldryn_categories',
|
|
8
|
+
'aldryn_newsblog',
|
|
9
|
+
'aldryn_people',
|
|
10
|
+
'aldryn_translation_tools',
|
|
11
|
+
'parler',
|
|
12
|
+
'sortedm2m',
|
|
13
|
+
'taggit',
|
|
14
|
+
]
|
example/settings/dev.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from cms_qe.settings.dev import * # noqa: F403
|
|
4
|
+
|
|
5
|
+
INSTALLED_APPS += [ # noqa: F405
|
|
6
|
+
'example',
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
AUTHENTICATION_BACKENDS = [
|
|
10
|
+
'axes.backends.AxesBackend',
|
|
11
|
+
'django.contrib.auth.backends.ModelBackend',
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
ROOT_URLCONF = 'example.urls'
|
|
15
|
+
WSGI_APPLICATION = 'example.wsgi.application'
|
|
16
|
+
|
|
17
|
+
BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
|
18
|
+
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
|
19
|
+
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
|
20
|
+
|
|
21
|
+
DATABASES = {
|
|
22
|
+
'default': {
|
|
23
|
+
'ENGINE': 'django.db.backends.sqlite3',
|
|
24
|
+
'NAME': os.path.join(BASE_DIR, '..', 'db.sqlite3'),
|
|
25
|
+
'TEST': {
|
|
26
|
+
'NAME': ':memory:',
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
example/urls.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from django.conf import settings
|
|
2
|
+
from django.urls import path
|
|
3
|
+
from django.views.static import serve
|
|
4
|
+
|
|
5
|
+
from cms_qe.urls import handler403, handler404, handler500, handler503, urlpatterns
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def serve_favicon(request):
|
|
9
|
+
"""Serve favicon.ico."""
|
|
10
|
+
return serve(request, 'favicon.ico', settings.STATIC_ROOT)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if settings.DEBUG:
|
|
14
|
+
urlpatterns += [
|
|
15
|
+
path('favicon.ico', serve_favicon),
|
|
16
|
+
]
|
example/wsgi.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
WSGI config for example project.
|
|
3
|
+
|
|
4
|
+
It exposes the WSGI callable as a module-level variable named ``application``.
|
|
5
|
+
|
|
6
|
+
For more information on this file, see
|
|
7
|
+
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
from django.core.wsgi import get_wsgi_application
|
|
13
|
+
|
|
14
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings.dev')
|
|
15
|
+
|
|
16
|
+
application = get_wsgi_application()
|
cms_qe/hooks.py
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
from types import MethodType
|
|
2
|
-
|
|
3
|
-
from django.apps import apps
|
|
4
|
-
from django.conf import settings
|
|
5
|
-
from django.contrib import messages
|
|
6
|
-
from django.contrib.auth.views import LoginView
|
|
7
|
-
from django.db import InternalError, connection
|
|
8
|
-
from django.http import HttpRequest, HttpResponseRedirect
|
|
9
|
-
from django.template.response import TemplateResponse
|
|
10
|
-
from django.urls import reverse
|
|
11
|
-
from django.utils.translation import gettext_lazy as _
|
|
12
|
-
from djangocms_alias.models import AliasContent
|
|
13
|
-
from menus.menu_pool import MenuRenderer, menu_pool
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def pg_is_in_recovery():
|
|
17
|
-
"""Return True when database is slave or False when database is master."""
|
|
18
|
-
with connection.cursor() as cursor:
|
|
19
|
-
if cursor.db.vendor != 'postgresql':
|
|
20
|
-
return False
|
|
21
|
-
cursor.execute("SELECT pg_is_in_recovery()")
|
|
22
|
-
return cursor.fetchone()[0]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class PgIsInRecoveryLoginView(LoginView):
|
|
26
|
-
template_name = 'admin/login.html'
|
|
27
|
-
url_page_name = "login"
|
|
28
|
-
|
|
29
|
-
def get(self, request, *args, **kwargs):
|
|
30
|
-
if pg_is_in_recovery():
|
|
31
|
-
messages.add_message(request, messages.WARNING,
|
|
32
|
-
_('The database is in recovery mode. Unable to login. Try it later.'))
|
|
33
|
-
return super().get(request, *args, **kwargs)
|
|
34
|
-
|
|
35
|
-
def post(self, request, *args, **kwargs):
|
|
36
|
-
if pg_is_in_recovery():
|
|
37
|
-
messages.add_message(request, messages.ERROR, _('Login failed. The database is in recovery mode.'))
|
|
38
|
-
return HttpResponseRedirect(reverse(self.url_page_name))
|
|
39
|
-
return super().post(request, *args, **kwargs)
|
|
40
|
-
|
|
41
|
-
def get_template_names(self):
|
|
42
|
-
if pg_is_in_recovery():
|
|
43
|
-
return ['pg_is_in_recovery_login.html']
|
|
44
|
-
return self.template_name
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class PgIsInRecoveryMenuRenderer(MenuRenderer):
|
|
48
|
-
|
|
49
|
-
def get_nodes(self, namespace=None, root_id=None, breadcrumb=False):
|
|
50
|
-
try:
|
|
51
|
-
return super().get_nodes(namespace, root_id, breadcrumb)
|
|
52
|
-
except InternalError:
|
|
53
|
-
if pg_is_in_recovery():
|
|
54
|
-
return []
|
|
55
|
-
raise
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def render_alias_content(request: HttpRequest, alias_content: AliasContent) -> TemplateResponse:
|
|
59
|
-
"""Render alias content with additionad css class alias-$name.
|
|
60
|
-
|
|
61
|
-
This is the same function as on the url
|
|
62
|
-
https://github.com/django-cms/djangocms-alias/blob/master/djangocms_alias/rendering.py#L4,
|
|
63
|
-
it just uses a different template. In the template, a css class is added by the alias name.
|
|
64
|
-
This is necessary so that the appropriate styles can be linked to it.
|
|
65
|
-
"""
|
|
66
|
-
template = "cms_qe/alias_content_preview.html"
|
|
67
|
-
context = {
|
|
68
|
-
"alias_content": alias_content,
|
|
69
|
-
"site_styles": settings.STYLES_FOR_ALIAS_ADMIN_PREVIEW,
|
|
70
|
-
}
|
|
71
|
-
return TemplateResponse(request, template, context)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def get_renderer(self, request: HttpRequest) -> PgIsInRecoveryMenuRenderer:
|
|
75
|
-
self.discover_menus()
|
|
76
|
-
return PgIsInRecoveryMenuRenderer(pool=self, request=request)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def patch_menu_pool_cachekey():
|
|
80
|
-
"""Skip exception when MenuRenderer attempts to write to read only database."""
|
|
81
|
-
menu_pool.get_renderer = MethodType(get_renderer, menu_pool)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def patch_alias():
|
|
85
|
-
"""Patch alias template preview."""
|
|
86
|
-
try:
|
|
87
|
-
extension = apps.get_app_config('cms').cms_extension
|
|
88
|
-
extension.toolbar_enabled_models[AliasContent] = render_alias_content
|
|
89
|
-
except KeyError:
|
|
90
|
-
pass
|
cms_qe/ldap.py
DELETED
cms_qe/settings/base/env.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
form .selector-chosen-title {
|
|
2
|
-
background-color: #00bbff;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
fieldset .fieldset-heading,
|
|
6
|
-
fieldset .inline-heading,
|
|
7
|
-
:not(.inline-related) .collapse summary {
|
|
8
|
-
background-color: #00bbff !important;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
fieldset h2.fieldset-heading {
|
|
12
|
-
color: white !important;
|
|
13
|
-
background-color: #00bbff !important;
|
|
14
|
-
font-weight: bold !important;
|
|
15
|
-
padding-left: 1em !important;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.selector .selector-chooser button.selector-add,
|
|
19
|
-
.selector .selector-chooser button.selector-remove {
|
|
20
|
-
width: 38px !important;
|
|
21
|
-
height: 32px !important;
|
|
22
|
-
padding: 0.4em 1em 1em 0.5em !important;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
:enabled.selector-add,
|
|
26
|
-
:enabled.selector-remove {
|
|
27
|
-
opacity: 1 !important;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.selector .selector-available button.selector-chooseall,
|
|
31
|
-
.selector .selector-chosen button.selector-clearall {
|
|
32
|
-
height: 32px !important;
|
|
33
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{% extends "djangocms_alias/base.html" %}
|
|
2
|
-
{% load i18n cms_tags static %}
|
|
3
|
-
|
|
4
|
-
{% if site_styles %}
|
|
5
|
-
{% block extrastyle %}
|
|
6
|
-
{{ block.super }}
|
|
7
|
-
{% for path in site_styles %}
|
|
8
|
-
<link rel="stylesheet" href="{% static path %}">
|
|
9
|
-
{% endfor %}
|
|
10
|
-
{% endblock %}
|
|
11
|
-
{% block base_css %}
|
|
12
|
-
{{ block.super }}
|
|
13
|
-
{% for path in site_styles %}
|
|
14
|
-
<link rel="stylesheet" href="{% static path %}">
|
|
15
|
-
{% endfor %}
|
|
16
|
-
{% endblock %}
|
|
17
|
-
{% endif %}
|
|
18
|
-
|
|
19
|
-
{% block aliases_content %}
|
|
20
|
-
<div class="cms-aliases-page container alias-{{ alias_content.name|slugify }}">
|
|
21
|
-
<h2 class="cms-aliases-page-heading" id="{{ alias_content.name|slugify }}">
|
|
22
|
-
<span class="cms-aliases-page-heading-inner">Alias: {{ alias_content.name }}</span>
|
|
23
|
-
</h2>
|
|
24
|
-
<div class="cms-aliases-detail">
|
|
25
|
-
{% render_placeholder alias_content.placeholder %}
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
{% endblock aliases_content %}
|
cms_qe/views/test_messages.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
from cms_qe.views.test_messages import TestMessagesView
|
|
3
|
-
|
|
4
|
-
urlpatterns = [
|
|
5
|
-
path("test-messages/", TestMessagesView.as_view(), name='test-messages'),
|
|
6
|
-
]
|
|
7
|
-
"""
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
from django.contrib import messages
|
|
11
|
-
from django.http import HttpResponseRedirect
|
|
12
|
-
from django.views.generic import RedirectView
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class TestMessagesView(RedirectView):
|
|
16
|
-
"""Test messages view."""
|
|
17
|
-
|
|
18
|
-
def get_redirect_url(self, *args: Any, **kwargs: Any) -> HttpResponseRedirect:
|
|
19
|
-
"""Prepare message and redirect to the next."""
|
|
20
|
-
msg = self.request.GET.get("msg", "Test message. ?type=all / debug / info / success / warning / error")
|
|
21
|
-
messages.set_level(self.request, messages.DEBUG)
|
|
22
|
-
if self.request.GET.get("type") in ("debug", "all"):
|
|
23
|
-
messages.debug(self.request, msg)
|
|
24
|
-
if self.request.GET.get("type") in ("info", "all"):
|
|
25
|
-
messages.info(self.request, msg)
|
|
26
|
-
if self.request.GET.get("type") in ("success", "all"):
|
|
27
|
-
messages.success(self.request, msg)
|
|
28
|
-
if self.request.GET.get("type") in ("warning", "all"):
|
|
29
|
-
messages.warning(self.request, msg)
|
|
30
|
-
if self.request.GET.get("type") in ("error", "all"):
|
|
31
|
-
messages.error(self.request, msg)
|
|
32
|
-
return self.request.GET.get("next", "/")
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Same as django.core.mail.backends.filebased.EmailBackend, but save logs with .eml extension.
|
|
2
|
-
import datetime
|
|
3
|
-
import os
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
from django.core.mail.backends.filebased import EmailBackend
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class EmlEmailBackend(EmailBackend):
|
|
10
|
-
"""Save logs with .eml extension."""
|
|
11
|
-
|
|
12
|
-
_fname: Optional[str]
|
|
13
|
-
|
|
14
|
-
def _get_filename(self):
|
|
15
|
-
"""Return a unique file name."""
|
|
16
|
-
if self._fname is None:
|
|
17
|
-
timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
18
|
-
fname = "%s-%s.eml" % (timestamp, abs(id(self)))
|
|
19
|
-
self._fname = os.path.join(self.file_path, fname)
|
|
20
|
-
return self._fname
|
|
File without changes
|
|
File without changes
|