django-cms-qe 3.6.1__py3-none-any.whl → 3.7.0__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 +8 -7
- cms_qe/hooks.py +90 -0
- cms_qe/ldap.py +4 -0
- cms_qe/settings/base/app.py +12 -4
- cms_qe/settings/base/cache.py +6 -4
- cms_qe/settings/base/cms.py +4 -1
- cms_qe/settings/base/database.py +7 -10
- cms_qe/settings/base/email.py +9 -11
- cms_qe/settings/base/env.py +3 -0
- cms_qe/settings/base/logging.py +2 -1
- cms_qe/settings/base/search.py +5 -1
- cms_qe/settings/base/security.py +2 -1
- cms_qe/settings/dev.py +25 -19
- cms_qe/static/cms_qe/css/fix-djangocms-admin-style.css +33 -0
- cms_qe/templates/admin/inc/extrastyle.html +2 -0
- cms_qe/templates/base.html +7 -4
- cms_qe/templates/cms_qe/alias_content_preview.html +28 -0
- cms_qe/templates/cms_qe/home.html +0 -2
- cms_qe/templates/pg_is_in_recovery_login.html +4 -0
- cms_qe/urls.py +2 -0
- cms_qe/utils.py +11 -17
- cms_qe/views/redirect_to_page.py +38 -0
- cms_qe/views/test_messages.py +32 -0
- cms_qe_auth/models.py +1 -1
- cms_qe_test/cms.py +22 -5
- cms_qe_test/mail_filebased_backend.py +20 -0
- {django_cms_qe-3.6.1.dist-info → django_cms_qe-3.7.0.dist-info}/METADATA +74 -34
- {django_cms_qe-3.6.1.dist-info → django_cms_qe-3.7.0.dist-info}/RECORD +32 -29
- {django_cms_qe-3.6.1.dist-info → django_cms_qe-3.7.0.dist-info}/WHEEL +1 -1
- {django_cms_qe-3.6.1.dist-info → django_cms_qe-3.7.0.dist-info}/top_level.txt +0 -1
- example/__init__.py +0 -0
- example/settings/__init__.py +0 -0
- example/settings/aldryn_newsblog.py +0 -14
- example/settings/dev.py +0 -29
- example/settings/selenium.py +0 -10
- example/urls.py +0 -16
- example/wsgi.py +0 -16
- {django_cms_qe-3.6.1.dist-info → django_cms_qe-3.7.0.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 djangocms_alias_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_alias "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_alias "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) -> list:
|
|
140
|
+
def get_export_headers(self, selected_fields=None) -> 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, instance, **kwargs):
|
|
157
|
+
value = super().export_field(field, instance, **kwargs)
|
|
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, instance):
|
|
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(instance)
|
|
183
|
+
return super().get_value(instance)
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
# Taken from https://github.com/django-import-export/django-import-export/issues/525#issuecomment-303046691
|
|
@@ -197,12 +197,13 @@ 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__()
|
|
200
201
|
|
|
201
202
|
# pylint: disable=keyword-arg-before-vararg
|
|
202
203
|
def clean(self, value, row=None, *args, **kwargs):
|
|
203
204
|
"""Returns the db value given the display value"""
|
|
204
205
|
return self.revert_choices.get(value, value) if value else None
|
|
205
206
|
|
|
206
|
-
def render(self, value, obj=None):
|
|
207
|
+
def render(self, value, obj=None, **kwargs):
|
|
207
208
|
"""Returns the display value given the db value"""
|
|
208
209
|
return self.choices.get(value, '')
|
cms_qe/hooks.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
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
ADDED
cms_qe/settings/base/app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Base settings for Django app.
|
|
3
3
|
"""
|
|
4
|
+
from .env import ENV
|
|
4
5
|
|
|
5
6
|
# Default primary key field type
|
|
6
7
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
|
@@ -8,8 +9,10 @@ Base settings for Django app.
|
|
|
8
9
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
9
10
|
|
|
10
11
|
SITE_ID = 1
|
|
12
|
+
CMS_CONFIRM_VERSION4 = True
|
|
13
|
+
DJANGOCMS_VERSIONING_ALLOW_DELETING_VERSIONS = True
|
|
11
14
|
|
|
12
|
-
INTERNAL_IPS = [
|
|
15
|
+
INTERNAL_IPS = ENV.list("INTERNAL_IPS", default=[])
|
|
13
16
|
|
|
14
17
|
META_USE_SITES = True
|
|
15
18
|
META_SITE_PROTOCOL = 'https'
|
|
@@ -47,8 +50,12 @@ INSTALLED_APPS = [
|
|
|
47
50
|
'treebeard', # Tree structure of pages and plugins.
|
|
48
51
|
'sekizai', # Static file management.
|
|
49
52
|
|
|
53
|
+
'djangocms_text',
|
|
54
|
+
'djangocms_link',
|
|
55
|
+
'djangocms_alias',
|
|
56
|
+
'djangocms_versioning',
|
|
57
|
+
|
|
50
58
|
# Other Django CMS's useful modules.
|
|
51
|
-
'djangocms_text_ckeditor',
|
|
52
59
|
'djangocms_googlemap',
|
|
53
60
|
|
|
54
61
|
# Django Filer's modules.
|
|
@@ -70,11 +77,13 @@ INSTALLED_APPS = [
|
|
|
70
77
|
'djangocms_frontend.contrib.collapse',
|
|
71
78
|
'djangocms_frontend.contrib.content',
|
|
72
79
|
'djangocms_frontend.contrib.grid',
|
|
80
|
+
'djangocms_frontend.contrib.icon',
|
|
81
|
+
'djangocms_frontend.contrib.image',
|
|
73
82
|
'djangocms_frontend.contrib.jumbotron',
|
|
74
83
|
'djangocms_frontend.contrib.link',
|
|
75
84
|
'djangocms_frontend.contrib.listgroup',
|
|
76
85
|
'djangocms_frontend.contrib.media',
|
|
77
|
-
'djangocms_frontend.contrib.
|
|
86
|
+
'djangocms_frontend.contrib.navigation',
|
|
78
87
|
'djangocms_frontend.contrib.tabs',
|
|
79
88
|
'djangocms_frontend.contrib.utilities',
|
|
80
89
|
|
|
@@ -83,7 +92,6 @@ INSTALLED_APPS = [
|
|
|
83
92
|
'constance',
|
|
84
93
|
'constance.backends.database',
|
|
85
94
|
'import_export',
|
|
86
|
-
'mailqueue',
|
|
87
95
|
|
|
88
96
|
# Aldryn forms
|
|
89
97
|
'aldryn_forms',
|
cms_qe/settings/base/cache.py
CHANGED
|
@@ -5,9 +5,11 @@ 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
|
+
|
|
8
13
|
CACHES = {
|
|
9
|
-
|
|
10
|
-
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
|
|
11
|
-
'LOCATION': '127.0.0.1:11211',
|
|
12
|
-
}
|
|
14
|
+
"default": ENV.cache("CACHE_URL", default="pymemcache://127.0.0.1:11211"),
|
|
13
15
|
}
|
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_ATTRIBUTES: dict[str, set] = {"iframe": set()}
|
|
45
45
|
|
|
46
46
|
# cmsplugin_filer_folder
|
|
47
47
|
CMSPLUGIN_FILER_FOLDER_STYLE_CHOICES = (
|
|
@@ -65,3 +65,6 @@ 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] = []
|
cms_qe/settings/base/database.py
CHANGED
|
@@ -5,15 +5,12 @@ 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
|
|
8
14
|
DATABASES = {
|
|
9
|
-
|
|
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
|
-
}
|
|
15
|
+
"default": ENV.db("DATABASE_URL", default='postgres://qe_user:password@/cms_qe'),
|
|
19
16
|
}
|
cms_qe/settings/base/email.py
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Mailing settings, by default app looks for smtp server.
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
DEFAULT_FROM_EMAIL = 'django_cms_qe@localhost'
|
|
4
|
+
from .env import ENV
|
|
5
|
+
|
|
6
|
+
EMAIL_HOST = ENV.str("EMAIL_HOST", default="localhost")
|
|
7
|
+
EMAIL_HOST_USER = ENV.str("EMAIL_USER", default="")
|
|
8
|
+
EMAIL_HOST_PASSWORD = ENV.str("EMAIL_PASSWORD", default="")
|
|
9
|
+
EMAIL_PORT = ENV.int("EMAIL_PORT", default=587) # TLS uses usually 587, not 22
|
|
10
|
+
EMAIL_USE_TLS = ENV.bool("EMAIL_USE_TLS", default=False)
|
|
11
|
+
EMAIL_SUBJECT_PREFIX = ENV.str("EMAIL_SUBJECT_PREFIX", default="") # Remove Django default prefix
|
|
12
|
+
DEFAULT_FROM_EMAIL = ENV.str("DEFAULT_FROM_EMAIL", default="django_cms_qe@localhost")
|
cms_qe/settings/base/logging.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Logging settings with base formatters and handlers.
|
|
3
3
|
"""
|
|
4
|
+
from .env import ENV
|
|
4
5
|
|
|
5
6
|
# Logging
|
|
6
7
|
# https://docs.djangoproject.com/en/1.11/topics/logging/
|
|
@@ -49,7 +50,7 @@ LOGGING = {
|
|
|
49
50
|
'propagate': True,
|
|
50
51
|
},
|
|
51
52
|
'': {
|
|
52
|
-
'level':
|
|
53
|
+
'level': ENV.str("LOGGER", default="ERROR"),
|
|
53
54
|
'handlers': ['console'],
|
|
54
55
|
},
|
|
55
56
|
}
|
cms_qe/settings/base/search.py
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
+
from .env import ENV
|
|
5
|
+
|
|
4
6
|
site_resolver = Path(__file__).resolve()
|
|
5
7
|
|
|
6
8
|
PROJECT_DIR = site_resolver.parent.parent.parent.parent
|
|
7
9
|
|
|
8
10
|
HAYSTACK_ROUTERS = ['aldryn_search.router.LanguageRouter']
|
|
9
11
|
HAYSTACK_ENGINE = 'cms_qe.whoosh.backend.AnalyzerWhooshEngine'
|
|
10
|
-
_HAYSTACK_PATH = os.path.normpath(os.path.join(PROJECT_DIR, 'whoosh_index'))
|
|
12
|
+
_HAYSTACK_PATH = ENV.str('HAYSTACK_PATH', default=os.path.normpath(os.path.join(PROJECT_DIR, 'whoosh_index')))
|
|
11
13
|
HAYSTACK_CONNECTIONS = {
|
|
12
14
|
'default': {'ENGINE': HAYSTACK_ENGINE, 'PATH': os.path.join(_HAYSTACK_PATH, 'default')},
|
|
13
15
|
'en': {'ENGINE': HAYSTACK_ENGINE, 'PATH': os.path.join(_HAYSTACK_PATH, 'en')},
|
|
14
16
|
}
|
|
15
17
|
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,10 +41,11 @@ 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
|
|
44
45
|
|
|
45
46
|
# Cookies.
|
|
46
47
|
|
|
47
|
-
SESSION_COOKIE_NAME =
|
|
48
|
+
SESSION_COOKIE_NAME = ENV.str("SESSION_COOKIE_NAME", default="sessionid")
|
|
48
49
|
SESSION_COOKIE_SECURE = True
|
|
49
50
|
|
|
50
51
|
# Secure headers.
|
cms_qe/settings/dev.py
CHANGED
|
@@ -8,6 +8,7 @@ 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
|
|
11
12
|
|
|
12
13
|
# Quick-start development settings - unsuitable for production
|
|
13
14
|
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
|
|
@@ -16,7 +17,7 @@ DEBUG = True
|
|
|
16
17
|
|
|
17
18
|
META_SITE_PROTOCOL = 'http'
|
|
18
19
|
|
|
19
|
-
SECRET_KEY =
|
|
20
|
+
SECRET_KEY = ENV.str("SECRET_KEY", default='secret')
|
|
20
21
|
|
|
21
22
|
SESSION_COOKIE_SECURE = False
|
|
22
23
|
|
|
@@ -38,30 +39,35 @@ MIDDLEWARE += [ # noqa: F405
|
|
|
38
39
|
site_resolver = Path(__file__).resolve()
|
|
39
40
|
|
|
40
41
|
PROJECT_DIR = site_resolver.parent.parent.parent
|
|
42
|
+
RUN_SITE_DIR = os.environ.get("VENV_PATH", PROJECT_DIR)
|
|
41
43
|
|
|
42
|
-
STATIC_ROOT = os.path.join(PROJECT_DIR, 'staticfiles')
|
|
44
|
+
STATIC_ROOT = ENV.str("STATIC_ROOT", default=os.path.join(PROJECT_DIR, 'staticfiles'))
|
|
45
|
+
MEDIA_ROOT = ENV.str("MEDIA_ROOT", default=os.path.join(RUN_SITE_DIR, 'media'))
|
|
43
46
|
|
|
44
47
|
# Caching
|
|
45
|
-
# https://docs.djangoproject.com/en/1.11/topics/cache/
|
|
46
|
-
|
|
47
48
|
CACHES = {
|
|
48
|
-
|
|
49
|
-
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
|
|
50
|
-
'LOCATION': os.path.join(PROJECT_DIR, 'django_cache'),
|
|
51
|
-
}
|
|
49
|
+
"default": ENV.cache("CACHE_URL", default=f'filecache://{os.path.join(RUN_SITE_DIR, "django_cache")}')
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
# Database
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
DATABASES = {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
database_path = os.path.join(RUN_SITE_DIR, 'db.sqlite3')
|
|
54
|
+
database_url_default = f"sqlite:///{database_path}"
|
|
55
|
+
DATABASES = {"default": ENV.db("DATABASE_URL", default=database_url_default)}
|
|
56
|
+
|
|
57
|
+
EMAIL_BACKEND = 'cms_qe_test.mail_filebased_backend.EmlEmailBackend'
|
|
58
|
+
EMAIL_FILE_PATH = ENV.str("EMAIL_FILE_PATH", default=os.path.join(RUN_SITE_DIR, 'django_mails'))
|
|
59
|
+
|
|
60
|
+
ALDRYN_FORMS_SUBMISSION_LIST_DISPLAY_FIELD = "aldryn_forms.admin.display_form_submission_data"
|
|
61
|
+
|
|
62
|
+
SITE_API_ROOT = "/api/v1/"
|
|
63
|
+
|
|
64
|
+
REST_FRAMEWORK = {
|
|
65
|
+
'EXCEPTION_HANDLER': 'cms_qe.api.utils.exception_handler',
|
|
66
|
+
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
# API views: [("path/", "module.api.views.RecordViewSet", "api-records"), ...]
|
|
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
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
}
|
cms_qe/templates/base.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% load i18n static cms_tags sekizai_tags %}
|
|
1
|
+
{% load i18n static cms_tags djangocms_alias_tags menu_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,17 +9,20 @@
|
|
|
9
9
|
{% include 'cms_qe/include/head.html' %}
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
|
-
{% include 'cms_qe/include/body_top.html' %}
|
|
13
12
|
{% cms_toolbar %}
|
|
13
|
+
{% block menu %}
|
|
14
|
+
<menu>{% show_menu 0 100 100 100 %}</menu>
|
|
15
|
+
{% endblock %}
|
|
16
|
+
{% include 'cms_qe/include/body_top.html' %}
|
|
14
17
|
{% block header %}
|
|
15
18
|
<header>
|
|
16
|
-
{%
|
|
19
|
+
{% static_alias "header" %}
|
|
17
20
|
</header>
|
|
18
21
|
{% endblock %}
|
|
19
22
|
{% block content %}{% endblock %}
|
|
20
23
|
{% block footers %}
|
|
21
24
|
<footer>
|
|
22
|
-
{%
|
|
25
|
+
{% static_alias "footer" %}
|
|
23
26
|
</footer>
|
|
24
27
|
{% endblock %}
|
|
25
28
|
{% include "cms_qe/include/body_bottom.html" %}
|
|
@@ -0,0 +1,28 @@
|
|
|
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/urls.py
CHANGED
|
@@ -14,6 +14,7 @@ from django.urls import include, path
|
|
|
14
14
|
from django.views.i18n import JavaScriptCatalog
|
|
15
15
|
|
|
16
16
|
from cms_qe.views.maintenance import HealthCheckView, ReloadSiteView
|
|
17
|
+
from cms_qe.views.redirect_to_page import RedirectToPage
|
|
17
18
|
from cms_qe.views.search_result import SiteSearchView
|
|
18
19
|
from cms_qe.views.security import SecurityTxtView
|
|
19
20
|
|
|
@@ -45,6 +46,7 @@ urlpatterns = [
|
|
|
45
46
|
path('site-search-result/', SiteSearchView.as_view(), name='site-search-result'),
|
|
46
47
|
path("healthcheck/", HealthCheckView.as_view(), name='healthcheck'), # Used by uwsgi in docker.
|
|
47
48
|
path("superuser/reload-site/", ReloadSiteView.as_view(), name='reload-site'),
|
|
49
|
+
path('redirect-to-page/', RedirectToPage.as_view(), name='redirect-to-page'),
|
|
48
50
|
]
|
|
49
51
|
|
|
50
52
|
# django-simple-captcha
|
cms_qe/utils.py
CHANGED
|
@@ -5,41 +5,35 @@ 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
|
|
8
9
|
from django.template import TemplateDoesNotExist
|
|
9
10
|
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 ``
|
|
17
|
-
message or put it to a mailqueue.
|
|
16
|
+
Returns a ``EmailMultiAlternatives`` instance from ``django.core.mail``.
|
|
18
17
|
|
|
19
18
|
Template should be without extension and you should create both ``.txt`` and ``.html`` version.
|
|
20
19
|
Second one is not mandatory but is good to provide it as well.
|
|
21
20
|
|
|
22
21
|
"""
|
|
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
|
-
|
|
32
22
|
template_txt = get_template(template + '.txt')
|
|
33
|
-
content = template_txt.render(kwargs)
|
|
34
|
-
email.content = content
|
|
35
23
|
|
|
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
|
+
)
|
|
36
30
|
try:
|
|
37
31
|
template_html = get_template(template + '.html')
|
|
32
|
+
msg.attach_alternative(template_html.render(kwargs), "text/html")
|
|
38
33
|
except TemplateDoesNotExist:
|
|
39
|
-
|
|
40
|
-
email.html_content = template_html.render(kwargs)
|
|
34
|
+
pass
|
|
41
35
|
|
|
42
|
-
return
|
|
36
|
+
return msg
|
|
43
37
|
|
|
44
38
|
|
|
45
39
|
def get_base_url(request) -> str:
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
import re
|
|
14
|
+
from django.views.generic import RedirectView
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RedirectToPage(RedirectView):
|
|
18
|
+
"""Redirect to page according to settings in constance."""
|
|
19
|
+
|
|
20
|
+
url = "/"
|
|
21
|
+
|
|
22
|
+
def get_redirect_url(self, *args, **kwargs):
|
|
23
|
+
try:
|
|
24
|
+
from constance import config
|
|
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):
|
|
29
|
+
line = line.strip()
|
|
30
|
+
groups = re.match(r"(?P<path>\S+)(\s+(?P<host>\S+))?", line.strip())
|
|
31
|
+
if groups is None:
|
|
32
|
+
continue
|
|
33
|
+
if groups['host'] is None:
|
|
34
|
+
return groups['path']
|
|
35
|
+
if groups['host'] == self.request.META.get("HTTP_HOST", self.request.META.get("SERVER_NAME")):
|
|
36
|
+
return groups['path']
|
|
37
|
+
continue
|
|
38
|
+
return self.url
|
|
@@ -0,0 +1,32 @@
|
|
|
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", "/")
|
cms_qe_auth/models.py
CHANGED
cms_qe_test/cms.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from cms import api
|
|
2
|
-
from cms.models import Placeholder
|
|
2
|
+
from cms.models import PageContent, 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
|
|
4
6
|
from django.contrib.auth.models import AnonymousUser
|
|
5
7
|
from django.contrib.messages.storage.fallback import FallbackStorage
|
|
6
8
|
from django.test import RequestFactory
|
|
9
|
+
from djangocms_versioning.constants import DRAFT, PUBLISHED
|
|
10
|
+
from djangocms_versioning.models import Version
|
|
7
11
|
from sekizai.context import SekizaiContext
|
|
8
12
|
|
|
9
13
|
|
|
@@ -11,6 +15,7 @@ def render_plugin(plugin, path='/', **data):
|
|
|
11
15
|
placeholder = Placeholder.objects.create(slot='test')
|
|
12
16
|
model_instance = api.add_plugin(placeholder, plugin, 'en', **data)
|
|
13
17
|
request = generate_get_request(path)
|
|
18
|
+
request.toolbar = CMSToolbar(request)
|
|
14
19
|
renderer = ContentRenderer(request=request)
|
|
15
20
|
context = SekizaiContext()
|
|
16
21
|
context.update({'request': request, })
|
|
@@ -35,16 +40,28 @@ def generate_post_request(path='', body=None):
|
|
|
35
40
|
|
|
36
41
|
|
|
37
42
|
# pylint: disable=dangerous-default-value
|
|
38
|
-
def create_page(title, language='en', page_params={}):
|
|
39
|
-
page_params.setdefault('published', True)
|
|
43
|
+
def create_page(title, language='en', page_params={}, state="publish"):
|
|
40
44
|
page_params.setdefault('overwrite_url', page_params.get('slug'))
|
|
41
|
-
|
|
45
|
+
page = api.create_page(title, 'cms_qe/home.html', language, **page_params)
|
|
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
|
|
42
55
|
|
|
43
56
|
|
|
44
57
|
# pylint: disable=dangerous-default-value
|
|
45
58
|
def create_text_page(title, language='en', page_params={}, plugin_params={}):
|
|
46
59
|
plugin_params.setdefault('body', 'shello')
|
|
47
60
|
page = create_page(title, language, page_params)
|
|
48
|
-
placeholder = page.
|
|
61
|
+
placeholder = page.get_placeholders(language).filter(slot="content").get()
|
|
49
62
|
api.add_plugin(placeholder, 'TextPlugin', language, **plugin_params)
|
|
50
63
|
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)
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-cms-qe
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
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,35 +23,41 @@ 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.10
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist: djangocms-
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: djangocms-
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: django-
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist:
|
|
29
|
+
Requires-Dist: django-cms~=4.1
|
|
30
|
+
Requires-Dist: django-filer~=3.3
|
|
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
|
|
36
|
+
Requires-Dist: easy-thumbnails[svg]~=2.10
|
|
37
|
+
Requires-Dist: argon2-cffi~=23.1
|
|
38
|
+
Requires-Dist: django-axes~=8.0
|
|
39
|
+
Requires-Dist: django-constance~=4.3
|
|
40
|
+
Requires-Dist: django-csp~=4.0
|
|
41
|
+
Requires-Dist: django-import-export~=4.3
|
|
41
42
|
Requires-Dist: django-tablib~=3.2
|
|
43
|
+
Requires-Dist: djangocms-file~=3.0
|
|
44
|
+
Requires-Dist: djangocms-googlemap~=2.2
|
|
45
|
+
Requires-Dist: djangocms-icon~=2.1
|
|
46
|
+
Requires-Dist: djangocms-link~=5.0
|
|
47
|
+
Requires-Dist: djangocms-picture~=4.1
|
|
48
|
+
Requires-Dist: python-environ~=0.4
|
|
49
|
+
Requires-Dist: django-haystack~=3.3
|
|
50
|
+
Requires-Dist: djangocms-aldryn-forms[captcha]~=8.0
|
|
51
|
+
Requires-Dist: djangocms-aldryn-search~=3.0
|
|
42
52
|
Requires-Dist: mailchimp3~=3.0
|
|
43
|
-
Requires-Dist: argon2-cffi~=21.3
|
|
44
|
-
Requires-Dist: djangocms-aldryn-forms[captcha]
|
|
45
|
-
Requires-Dist: djangocms-aldryn-search
|
|
46
|
-
Requires-Dist: django-haystack~=3.2
|
|
47
|
-
Requires-Dist: pymemcache~=4.0
|
|
48
53
|
Requires-Dist: whoosh~=2.7
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist: django-
|
|
52
|
-
Requires-Dist:
|
|
53
|
-
Requires-Dist: drf-spectacular
|
|
54
|
+
Requires-Dist: Markdown~=3.8
|
|
55
|
+
Requires-Dist: django-filter~=25.1
|
|
56
|
+
Requires-Dist: django-rest-knox~=5.0
|
|
57
|
+
Requires-Dist: djangorestframework~=3.16
|
|
58
|
+
Requires-Dist: drf-spectacular~=0.28
|
|
54
59
|
Provides-Extra: dev
|
|
60
|
+
Requires-Dist: django-simple-captcha~=0.5; extra == "dev"
|
|
55
61
|
Requires-Dist: django-debug-toolbar~=4.1; extra == "dev"
|
|
56
62
|
Requires-Dist: django-extensions~=3.2; extra == "dev"
|
|
57
63
|
Provides-Extra: test
|
|
@@ -61,15 +67,16 @@ Requires-Dist: mypy; extra == "test"
|
|
|
61
67
|
Requires-Dist: pylint; extra == "test"
|
|
62
68
|
Requires-Dist: pylint-django; extra == "test"
|
|
63
69
|
Requires-Dist: pytest~=6.2; extra == "test"
|
|
64
|
-
Requires-Dist: pytest-
|
|
65
|
-
Requires-Dist: pytest-
|
|
66
|
-
Requires-Dist: pytest-
|
|
67
|
-
Requires-Dist: pytest-
|
|
68
|
-
Requires-Dist: pytest-
|
|
69
|
-
Requires-Dist: pytest-
|
|
70
|
-
Requires-Dist:
|
|
71
|
-
Requires-Dist:
|
|
72
|
-
Requires-Dist:
|
|
70
|
+
Requires-Dist: pytest-cov~=6.2; extra == "test"
|
|
71
|
+
Requires-Dist: pytest-data~=0.4; extra == "test"
|
|
72
|
+
Requires-Dist: pytest-django~=3.9; extra == "test"
|
|
73
|
+
Requires-Dist: pytest-env~=0.6; extra == "test"
|
|
74
|
+
Requires-Dist: pytest-pythonpath~=0.7; extra == "test"
|
|
75
|
+
Requires-Dist: pytest-sugar~=0.9; extra == "test"
|
|
76
|
+
Requires-Dist: pytest-watch~=4.2; extra == "test"
|
|
77
|
+
Requires-Dist: PyVirtualDisplay~=1.3; extra == "test"
|
|
78
|
+
Requires-Dist: webdriverwrapper~=2.8; extra == "test"
|
|
79
|
+
Requires-Dist: django-simple-captcha~=0.5; extra == "test"
|
|
73
80
|
Requires-Dist: testfixtures; extra == "test"
|
|
74
81
|
Requires-Dist: tzdata; extra == "test"
|
|
75
82
|
Provides-Extra: build
|
|
@@ -80,7 +87,7 @@ Requires-Dist: psycopg2; extra == "psql"
|
|
|
80
87
|
Provides-Extra: mysql
|
|
81
88
|
Requires-Dist: mysqlclient~=2.2; extra == "mysql"
|
|
82
89
|
Provides-Extra: newsblog
|
|
83
|
-
Requires-Dist: djangocms-aldryn-newsblog; extra == "newsblog"
|
|
90
|
+
Requires-Dist: djangocms-aldryn-newsblog~=4.0; extra == "newsblog"
|
|
84
91
|
Dynamic: author
|
|
85
92
|
Dynamic: author-email
|
|
86
93
|
Dynamic: classifier
|
|
@@ -143,3 +150,36 @@ To find more useful commands, run just `make`.
|
|
|
143
150
|
## Upgrade
|
|
144
151
|
|
|
145
152
|
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,13 +2,15 @@ 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=3MflO_EmaCrlqqa-cTMOiRirsp3r4mxdQNt-Zh5FtzY,8242
|
|
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
|
|
7
9
|
cms_qe/monitoring.py,sha256=5t_o7o0htmAAxVjkN2oz0O0v9XdzfePhSfPGcLNPmE8,769
|
|
8
10
|
cms_qe/signals.py,sha256=MbuLSxPlJA147LEg-lDWDoUNTV1y0OKjwoI3HzgR97g,1253
|
|
9
11
|
cms_qe/staticfiles.py,sha256=OHkfDfpIxN0B-eCRagZzHDHyBgaulcyYgKhp_3mPZuk,1363
|
|
10
|
-
cms_qe/urls.py,sha256=
|
|
11
|
-
cms_qe/utils.py,sha256=
|
|
12
|
+
cms_qe/urls.py,sha256=npDzzW9SgLVMZECTyOUL5Cpw7RxeuuNssTKOXuXuxtM,3247
|
|
13
|
+
cms_qe/utils.py,sha256=52ETz4NKv8xyBrMJ4yDUTfUBaO6Owp-5_IHfxDftQEE,2913
|
|
12
14
|
cms_qe/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
15
|
cms_qe/api/constants.py,sha256=pdSziATRm6yUaaPBYoD07JXcULMvKD0h5RdNTPpG0rM,64
|
|
14
16
|
cms_qe/api/permissions.py,sha256=QKSll8wVOWKNbvX_FsC9CRKbPVcT2s5FM81_fnqeEQg,409
|
|
@@ -33,7 +35,7 @@ cms_qe/boilerplates/bootstrap3/static/cms_qe/js/bootstrap.min.js,sha256=U5ZEeKfG
|
|
|
33
35
|
cms_qe/boilerplates/bootstrap3/static/cms_qe/js/jquery_3.2.1.min.js,sha256=hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4,86659
|
|
34
36
|
cms_qe/boilerplates/bootstrap3/static/cms_qe/js/npm.js,sha256=x6qCoap9RSJKONkm0q2v9_5K71vNr6Kke9rAV_RCLC0,484
|
|
35
37
|
cms_qe/boilerplates/bootstrap3/templates/cms_qe/error.html,sha256=gHFQbT2KPAwnhos6uMk4gvijDjubwiOA-j_q9fASBZM,375
|
|
36
|
-
cms_qe/boilerplates/bootstrap3/templates/cms_qe/home.html,sha256=
|
|
38
|
+
cms_qe/boilerplates/bootstrap3/templates/cms_qe/home.html,sha256=itXnWbX_-Z9jIgdca25obWjwVCTT0Jy6FxWTD5aUvyU,1474
|
|
37
39
|
cms_qe/boilerplates/bootstrap3/templates/cmsplugin_filer_folder/plugins/folder/gallery.html,sha256=ZAbkXcsJ6mwAJt0vQNd55ZWB-BhJ_gtvtbnKx8PysV8,3107
|
|
38
40
|
cms_qe/haystack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
41
|
cms_qe/haystack/forms.py,sha256=4FyieMfxfE6h2dcUaWAZJ18rEOAcnMVb2zLZ60iCbVA,912
|
|
@@ -52,26 +54,31 @@ cms_qe/middleware/page_status_code.py,sha256=J-Ezet9ban9rnjWaSuRss9gOz5h7uCCyL46
|
|
|
52
54
|
cms_qe/migrations/0001_api_permissions.py,sha256=KPJYBdX3dWYEbUswSiIhkhDV6FcjXG-MPfC2aYwt7Wc,672
|
|
53
55
|
cms_qe/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
56
|
cms_qe/settings/__init__.py,sha256=GJwHXMHwMuGYE-3ZzePJ-26I2WwE8bAIMUDoiTFr0L8,982
|
|
55
|
-
cms_qe/settings/dev.py,sha256=
|
|
57
|
+
cms_qe/settings/dev.py,sha256=A0LJ1cnoGqq7p7KInfqI-DNL8NqKaHbe5dByRIptknc,2143
|
|
56
58
|
cms_qe/settings/unittest.py,sha256=folLIMJb1Arh60_Sn0eNQrvIlx0OsAs6v1tDfyRZVuQ,514
|
|
57
59
|
cms_qe/settings/base/__init__.py,sha256=5yHfne9gPD_xuTaG3voZP23yzuCwROmif2mmKs-hG_A,446
|
|
58
|
-
cms_qe/settings/base/app.py,sha256=
|
|
60
|
+
cms_qe/settings/base/app.py,sha256=rWkemCai4k6PBxcx9ga6ggF32lUUVyh30Vp_7QU22Rg,4469
|
|
59
61
|
cms_qe/settings/base/auth.py,sha256=OTr1LJ4RSMZm8STs4Q3pwPXmQoURax8OKLJ8eAj7PW4,395
|
|
60
|
-
cms_qe/settings/base/cache.py,sha256=
|
|
61
|
-
cms_qe/settings/base/cms.py,sha256=
|
|
62
|
+
cms_qe/settings/base/cache.py,sha256=yBCvIIW25bSBD9nzVbPQvsPfw-pkOmcnLO7OPwzXPWo,337
|
|
63
|
+
cms_qe/settings/base/cms.py,sha256=hzl10CwswfQJkIfn4WoFJUmoumwC2smhSl8IR4VxkLM,1990
|
|
62
64
|
cms_qe/settings/base/constants.py,sha256=Rdq6ESg_J2B1Xm-ImEYM8pmsid-LqkSR7LXQdb3wlZU,7899
|
|
63
|
-
cms_qe/settings/base/database.py,sha256=
|
|
64
|
-
cms_qe/settings/base/email.py,sha256=
|
|
65
|
+
cms_qe/settings/base/database.py,sha256=_i3OJMRcrcI17VJeqY66JNOpAOXkhq570lRi0RVpzGw,354
|
|
66
|
+
cms_qe/settings/base/email.py,sha256=WkTj4V4lMZ3BG5AvHGPqulZ8T_cQMrvXiLj_NhLmpZs,576
|
|
67
|
+
cms_qe/settings/base/env.py,sha256=Oe10oSrA7QlD9TBDnEup8mtNTd1pXyaO5OThtUW8UVQ,36
|
|
65
68
|
cms_qe/settings/base/i18n.py,sha256=n_7esPYSbf9Wj-T23uWds7tCvQ0ol9MfyMtKzy009sM,355
|
|
66
|
-
cms_qe/settings/base/logging.py,sha256=
|
|
69
|
+
cms_qe/settings/base/logging.py,sha256=NnhPZnPX6zqobi4Ekx5euOnCD3Rw_Sb7jOl0tl80Vv0,1368
|
|
67
70
|
cms_qe/settings/base/path.py,sha256=s0eOmSDOWfjjI5onp28y2S2UKwCYFRDGeoUsZla6-og,410
|
|
68
|
-
cms_qe/settings/base/search.py,sha256=
|
|
69
|
-
cms_qe/settings/base/security.py,sha256=
|
|
71
|
+
cms_qe/settings/base/search.py,sha256=Vp6ROmo2x3ZaMrnHhNBjR3dX_r7BvIkcG9CPXmlZhiE,725
|
|
72
|
+
cms_qe/settings/base/security.py,sha256=fLaVfmqdF6-IZ0oppnV3Xs6KGARx7u9fYvWMwRJA3LM,4557
|
|
70
73
|
cms_qe/settings/base/template.py,sha256=bITmA7XkoqbDpefWWOBsEiPtCREzFfHkUuFvGxJVLK4,1082
|
|
71
|
-
cms_qe/
|
|
74
|
+
cms_qe/static/cms_qe/css/fix-djangocms-admin-style.css,sha256=sf_9yH_rKSts9L0OQ1vN5t32PTyjBuwfHZnDCN0GTX4,805
|
|
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
|
|
72
77
|
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
|
|
73
80
|
cms_qe/templates/cms_qe/error.html,sha256=1wNCO-ToNoM-HBnfq0Id_W8m_epmOEYcoozRhhHth5U,322
|
|
74
|
-
cms_qe/templates/cms_qe/home.html,sha256=
|
|
81
|
+
cms_qe/templates/cms_qe/home.html,sha256=zT4fnq9V6CsVkGXs_iFMGE4RvcMAeWvs4r0XTiHcLwA,114
|
|
75
82
|
cms_qe/templates/cms_qe/internal_error.html,sha256=n4JJ80KNHyhiSxGLQadCn9KmctnFABcwLU4KuZly8A4,251
|
|
76
83
|
cms_qe/templates/cms_qe/search_result.html,sha256=5XDX4nhRDkSJq_EdW95p8CuEN1Yy14OG9UC3WDz7TXI,310
|
|
77
84
|
cms_qe/templates/cms_qe/include/body_bottom.html,sha256=t-B_SA2AFPmTC5hnDANyR9O9tmH3-hzGTLoRPi9lgIY,29
|
|
@@ -89,8 +96,10 @@ cms_qe/views/__init__.py,sha256=3b5FCZ5MaqgiWglC7c5mfvP3WYLWTtNp3YpVb9BgYi8,106
|
|
|
89
96
|
cms_qe/views/errors.py,sha256=zUbCoyXy_MPsQv3UV1mgq-q2bwqPw9G4KgKU2-oue4w,3169
|
|
90
97
|
cms_qe/views/maintenance.py,sha256=Q410LCeeihRWhIJ-zzRpFSjfvA6xhgr6NJlNAoTNO2U,1658
|
|
91
98
|
cms_qe/views/monitoring.py,sha256=1r2s_jm6B6P0gEmiqjH9m3loUW3BmJivvpg6qcUOxVM,1909
|
|
99
|
+
cms_qe/views/redirect_to_page.py,sha256=MEgwDfjRYbMhCduimvIz_Do6NnKFRzjuSnuTBZmLnYI,1176
|
|
92
100
|
cms_qe/views/search_result.py,sha256=H1eMOmtONnWqBDsBvz3MartyHhh42vyi0jPoxWb0X8c,296
|
|
93
101
|
cms_qe/views/security.py,sha256=SNdJe4NSm1vuOGchVF3VqlmFDopt9xYoO-b4Y0UxkFU,1108
|
|
102
|
+
cms_qe/views/test_messages.py,sha256=ULHdXwjSmQxCxFF1hzBzpDa5MltGwyIF8DjQPb7N-7M,1281
|
|
94
103
|
cms_qe/whoosh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
104
|
cms_qe/whoosh/backend.py,sha256=YOVJGz3htWdcSUbYtX2a9VqywAU3EJP_EvxXHCY0QVA,5418
|
|
96
105
|
cms_qe_analytical/LICENSE.txt,sha256=ptQIrnsiWFFf2LZ60DTAO6XA7CQYFuwhX1m4kzhv5_8,1072
|
|
@@ -107,7 +116,7 @@ cms_qe_auth/cms_menus.py,sha256=UxzzuMfOJCC_EiCkV2__6R5JKV9q1WGbTEgO7yLy8rE,1675
|
|
|
107
116
|
cms_qe_auth/cms_plugins.py,sha256=USiNHaWdIJqPFUMLOjhuVam4nwOckujg1uguXNIs798,1575
|
|
108
117
|
cms_qe_auth/fixtures.py,sha256=hQO75OnBmU4NiT_GF-oW4lU50FrLDgGF-gfouYeLfRI,784
|
|
109
118
|
cms_qe_auth/forms.py,sha256=x7sdFoOrKBLTJXqESedpIh6Kc1k5zZhL4vwnmhj1gH8,1137
|
|
110
|
-
cms_qe_auth/models.py,sha256=
|
|
119
|
+
cms_qe_auth/models.py,sha256=ytcbh-rT36IQmOXxk4yef1xRq2RVvTzneORAC7pvWds,2713
|
|
111
120
|
cms_qe_auth/token.py,sha256=DG4Bu8AVV-d1ayL4Oc9DXNnERt1sstrll80RBGrplx0,224
|
|
112
121
|
cms_qe_auth/urls.py,sha256=RCgr9t1YonE0yR_8gXiXZIGESvQfrwVwlKhBOWmgxkw,2040
|
|
113
122
|
cms_qe_auth/utils.py,sha256=JYZUzQhUE_kycVBRBNi-fmGy5WtjIwc3_qsGxOVrNR0,2972
|
|
@@ -3940,7 +3949,8 @@ cms_qe_table/templates/cms_qe/table/table_widget.html,sha256=tsjlS5Mc_6iALFk0QIe
|
|
|
3940
3949
|
cms_qe_table/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3941
3950
|
cms_qe_table/templatetags/cms_qe_table_filters.py,sha256=eFBB2FoCcpQRAknMIJLac0ts18w8XIODbouuJlP0ty4,782
|
|
3942
3951
|
cms_qe_test/__init__.py,sha256=-Vc3K2g4JFSE2qw5AvuTGi4rwQGMOXAEycrjgFWk1BQ,121
|
|
3943
|
-
cms_qe_test/cms.py,sha256=
|
|
3952
|
+
cms_qe_test/cms.py,sha256=cJs5ZHbyPamTBuIMOhT1R2DR6teKYwhbZeuY-M-7i8I,2660
|
|
3953
|
+
cms_qe_test/mail_filebased_backend.py,sha256=9q3YuR-WcfhNOJc6hWclJmwRs949gzGFm6Eb3W7CjeI,645
|
|
3944
3954
|
cms_qe_video/__init__.py,sha256=2iOdITrw_UvFcQpFA0rhUWBCRe2qvTuDvltp5Q233cc,1070
|
|
3945
3955
|
cms_qe_video/cms_plugins.py,sha256=kqJX5eb-pYutxO-_0UnO784QpTwOb5Eudo6bW2NXaZg,3020
|
|
3946
3956
|
cms_qe_video/fixtures.py,sha256=0oGo7Ufh3XwaLaMjcGN7CFao_BetcQ6xtikNeAHdqvs,701
|
|
@@ -3959,14 +3969,7 @@ cms_qe_video/templates/cms_qe/video/video_source_file.html,sha256=QJF5fs88s9Fznp
|
|
|
3959
3969
|
cms_qe_video/templates/cms_qe/video/video_widget.html,sha256=Yumciq6bGlAYI1lYx5j9V6IF8QYrncNYygPTkXEz6Wk,925
|
|
3960
3970
|
cms_qe_video/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3961
3971
|
cms_qe_video/templatetags/cms_qe_video.py,sha256=NR_mGv91J0rEreZrQjCzaaXSrZsKvrSas12wMJ-Dg24,1168
|
|
3962
|
-
django_cms_qe-3.
|
|
3963
|
-
example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3964
|
-
example/urls.py,sha256=H-IJsRGFVZGw6FD9gvK-0B0dLeSOsduziHvDvcHCQZ0,399
|
|
3965
|
-
example/wsgi.py,sha256=lCKhvtFZlorSIA8qYEqc3pZ1Oflrz_Tc696MWJ62ue4,396
|
|
3966
|
-
example/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3967
|
-
example/settings/aldryn_newsblog.py,sha256=iQ5idy9rZR_N5IJzogc7R3PK3RIN7OMw7ksSIIIxPDk,276
|
|
3968
|
-
example/settings/dev.py,sha256=TGGlSzh9ZDh54Z2X5i6mz7Ja3lT_qBqw9MHX3EnMs9o,676
|
|
3969
|
-
example/settings/selenium.py,sha256=pRi8pIQIiYA0Y_yZsg7M63npHMRcUsFF7gZTr602yPY,215
|
|
3972
|
+
django_cms_qe-3.7.0.dist-info/licenses/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
|
|
3970
3973
|
test_selenium/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3971
3974
|
test_selenium/browser.py,sha256=OcfqxDa9OtL7M5CSwfIxtzToMUEhqGLvditemPeEUNo,1437
|
|
3972
3975
|
test_selenium/conftest.py,sha256=mAptaAyj7a1hbUPDRWBBs1qL0TJ8Fma7Mch6PZwgtNo,220
|
|
@@ -3980,7 +3983,7 @@ test_selenium/pages/cms/__init__.py,sha256=_qe4YZYaQbrXp7Szmmeo4TUSkXlE5Rozu8E3t
|
|
|
3980
3983
|
test_selenium/pages/cms/login.py,sha256=UPzJQcYff8NUAT4nvmfQoJQxzOJyPrJ_cKtH35NVfNg,521
|
|
3981
3984
|
test_selenium/pages/cms/page.py,sha256=YQnpZkopfVnhoyQKpRDGqjNeV6xUl-pEHjEcZ9HRiPk,489
|
|
3982
3985
|
test_selenium/pages/cms/wizard.py,sha256=yatbXH-rf1ap4O1hY0I13WikM3zkm_NrAiSK6bqENIU,545
|
|
3983
|
-
django_cms_qe-3.
|
|
3984
|
-
django_cms_qe-3.
|
|
3985
|
-
django_cms_qe-3.
|
|
3986
|
-
django_cms_qe-3.
|
|
3986
|
+
django_cms_qe-3.7.0.dist-info/METADATA,sha256=JPaPrE76CgXO2VeTxyt0VNbQQWn0arzmOgJwuaRdjv4,6234
|
|
3987
|
+
django_cms_qe-3.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
3988
|
+
django_cms_qe-3.7.0.dist-info/top_level.txt,sha256=fQYSfQoprw1NXhYY-I8AzsPk-Rgst1REh3iOUvwAbkM,164
|
|
3989
|
+
django_cms_qe-3.7.0.dist-info/RECORD,,
|
example/__init__.py
DELETED
|
File without changes
|
example/settings/__init__.py
DELETED
|
File without changes
|
|
@@ -1,14 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
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/settings/selenium.py
DELETED
example/urls.py
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
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()
|
|
File without changes
|