From b6548812a23390d7dc17382d918ee8d3639b3355 Mon Sep 17 00:00:00 2001 From: Angelo Dini Date: Tue, 16 Jan 2024 14:08:22 +0100 Subject: [PATCH] update code --- .coveragerc | 18 +++++++ .editorconfig | 31 ++++++++++++ .github/workflows/default.yml | 61 +++++++++++++++++++++++ .gitignore | 33 ++++++++++--- CHANGELOG.rst | 6 ++- LICENSE.txt => LICENSE | 0 MANIFEST.in | 3 ++ README.rst | 14 +++--- aldryn_config.py | 30 +++++++++--- aldryn_django_cms/models.py | 1 - aldryn_django_cms/urls.py | 10 ++-- aldryn_django_cms/urls_i18n.py | 8 ++- aldryn_django_cms/utils.py | 9 +--- aldryn_django_cms/views.py | 9 +--- setup.cfg | 27 ++++++++++ setup.py | 90 ++++++++++++++++++++++------------ tests/requirements.txt | 9 ++++ tests/settings.py | 22 +++++++++ tests/test_migrations.py | 30 ++++++++++++ 19 files changed, 331 insertions(+), 80 deletions(-) create mode 100644 .coveragerc create mode 100644 .editorconfig create mode 100644 .github/workflows/default.yml rename LICENSE.txt => LICENSE (100%) create mode 100644 MANIFEST.in create mode 100644 setup.cfg create mode 100644 tests/requirements.txt create mode 100644 tests/settings.py create mode 100644 tests/test_migrations.py diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..5cfbddd --- /dev/null +++ b/.coveragerc @@ -0,0 +1,18 @@ +[run] +branch = True +source = aldryn_django_cms +omit = + migrations/* + tests/* + +[report] +exclude_lines = + pragma: no cover + def __repr__ + if self.debug: + if settings.DEBUG + raise AssertionError + raise NotImplementedError + if 0: + if __name__ == .__main__.: +ignore_errors = True \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..adafbd5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,31 @@ +# editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 80 + +[*.py] +max_line_length = 120 +quote_type = single + +[*.{scss,js,html}] +max_line_length = 120 +indent_style = space +quote_type = double + +[*.js] +max_line_length = 120 +quote_type = single + +[*.rst] +max_line_length = 80 + +[*.yml] +indent_size = 2 diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml new file mode 100644 index 0000000..3711323 --- /dev/null +++ b/.github/workflows/default.yml @@ -0,0 +1,61 @@ +name: Checks + +on: [push] + +jobs: + flake8: + name: flake8 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install flake8 + run: pip install --upgrade flake8 + - name: Run flake8 + uses: liskin/gh-problem-matcher-wrap@v1 + with: + linters: flake8 + run: flake8 + + isort: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - run: python -m pip install isort + - name: isort + uses: liskin/gh-problem-matcher-wrap@v1 + with: + linters: isort + run: isort -c --df aldryn_django_cms + + unit-tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.8", "3.9"] + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install packaging + pip install -r tests/requirements.txt + python setup.py install + - name: Run coverage + run: coverage run setup.py test + - name: Upload Coverage to Codecov + uses: codecov/codecov-action@v1 diff --git a/.gitignore b/.gitignore index e1351f4..63bab6e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,27 @@ -/settings.json -.DS_STORE -*.pyc -aldryn_django_cms.egg-info -build -dist +*.py[cod] +*$py.class +*.egg-info +*.log +*.pot +.DS_Store +.coverage/ +.eggs/ +.idea/ +.project/ +.pydevproject/ +.vscode/ +.settings/ +.tox/ +__pycache__/ +build/ +dist/ +env/ + +/~ +/node_modules +.sass-cache +*.css.map +npm-debug.log +package-lock.json + +local.sqlite diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 340b772..f07bb6a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,10 @@ -CHANGELOG ========= +Changelog +========= + 4.0.1.14.dev2 (2022-07-15) ---------------------------- +-------------------------- * Use 4.0.1.dev2 release of django CMS. diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..b751087 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include LICENSE +include README.rst +recursive-exclude * *.py[co] diff --git a/README.rst b/README.rst index ad9e307..2d42991 100644 --- a/README.rst +++ b/README.rst @@ -92,14 +92,14 @@ Once satisfied: #. Notify the team via Slack. -.. |build| image:: https://travis-ci.org/divio/aldryn-django-cms.svg?branch=support/3.9.x - :target: https://travis-ci.org/divio/aldryn-django-cms -.. |coverage| image:: https://codecov.io/gh/divio/aldryn-django-cms/branch/support/3.9.x/graph/badge.svg +.. |build| image:: https://github.com/divio/aldryn-django-cms/actions/workflows/default.yml/badge.svg?branch=support/4.0.x + :target: https://github.com/divio/aldryn-django-cms/actions +.. |coverage| image:: https://codecov.io/gh/divio/aldryn-django-cms/branch/support/4.0.x/graph/badge.svg :target: https://codecov.io/gh/divio/aldryn-django-cms -.. |python| image:: https://img.shields.io/badge/python-3.6%20%7C%C2%A03.7%20%7C%C2%A03.8%20%7C%C2%A03.9-blue.svg +.. |python| image:: https://img.shields.io/badge/python-3.8%20%7C%C2%A03.9%20%7C%C2%A03.10%20%7C%C2%A03.11-blue.svg :target: https://pypi.org/project/aldryn-django-cms/ -.. |django| image:: https://img.shields.io/badge/django-2.2%20%7C%203.1%20%7C%C2%A03.2-blue.svg +.. |django| image:: https://img.shields.io/badge/django-3.2%20%7C%203.1%20%7C%C2%A04.2-blue.svg :target: https://www.djangoproject.com/ -.. |djangocms| image:: https://img.shields.io/badge/django%20CMS-3.9-blue.svg - :target: https://www.django-cms.org/ \ No newline at end of file +.. |djangocms| image:: https://img.shields.io/badge/django%20CMS-4.0-blue.svg + :target: https://www.django-cms.org/ diff --git a/aldryn_config.py b/aldryn_config.py index b6339b7..d8ae259 100644 --- a/aldryn_config.py +++ b/aldryn_config.py @@ -1,9 +1,9 @@ -# -*- coding: utf-8 -*- import json import os from aldryn_client import forms + SYSTEM_FIELD_WARNING = 'WARNING: this field is auto-written. Please do not change it here.' @@ -27,7 +27,7 @@ class Form(forms.BaseForm): 'overridden if the project supplies a CMS_TEMPLATES setting. See Manage templates in your django CMS project for more information.' ), ) @@ -49,8 +49,10 @@ class Form(forms.BaseForm): def to_settings(self, data, settings): from functools import partial + from django.urls import reverse_lazy - from aldryn_addons.utils import boolean_ish, djsenv + + from aldryn_addons.utils import djsenv env = partial(djsenv, settings=settings) @@ -83,13 +85,19 @@ def to_settings(self, data, settings): 'cms.context_processors.cms_settings', ]) - settings['MIDDLEWARE'].extend([ + middlewares = [ 'cms.middleware.user.CurrentUserMiddleware', 'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.language.LanguageCookieMiddleware', - ]) - settings['MIDDLEWARE'].insert(0, 'cms.middleware.utils.ApphookReloadMiddleware',) + ] + + if settings.get('MIDDLEWARE_CLASSES', None): + settings['MIDDLEWARE_CLASSES'].extend(middlewares) + settings['MIDDLEWARE_CLASSES'].insert(0, 'cms.middleware.utils.ApphookReloadMiddleware', ) + else: + settings['MIDDLEWARE'].extend(middlewares) + settings['MIDDLEWARE'].insert(0, 'cms.middleware.utils.ApphookReloadMiddleware', ) settings['ADDON_URLS_I18N_LAST'] = 'cms.urls' @@ -114,7 +122,7 @@ def to_settings(self, data, settings): with open(old_cms_templates_json) as fobj: templates = json.load(fobj) else: - templates= settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) + templates = settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) settings['CMS_TEMPLATES'] = templates @@ -157,7 +165,6 @@ def to_settings(self, data, settings): settings['PARLER_LANGUAGES'].update({'default': parler_defaults}) - # aldryn_snake TEMPLATE_CONTEXT_PROCESSORS = settings['TEMPLATES'][0]['OPTIONS']['context_processors'] TEMPLATE_CONTEXT_PROCESSORS.extend([ 'aldryn_snake.template_api.template_processor', @@ -198,6 +205,10 @@ def to_settings(self, data, settings): # django-robots settings['INSTALLED_APPS'].append('robots') + settings['MIGRATION_COMMANDS'].append( + 'python manage.py cms fix-tree' + ) + # default plugins settings['INSTALLED_APPS'].extend([ # required by aldryn-forms @@ -216,6 +227,9 @@ def to_settings(self, data, settings): # stage sso enabled # add internal endpoints that do not require authentication settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append(reverse_lazy('cms-check-uninstall')) + # this is an internal django-cms url + # which gets called when a user logs out from toolbar + settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append(reverse_lazy('admin:cms_page_resolve')) # Prevent injecting random comments to counter BREACH/CRIME attacks # into the page tree snippets, as the javascript parsing the result diff --git a/aldryn_django_cms/models.py b/aldryn_django_cms/models.py index 40a96af..e69de29 100644 --- a/aldryn_django_cms/models.py +++ b/aldryn_django_cms/models.py @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/aldryn_django_cms/urls.py b/aldryn_django_cms/urls.py index 254ec99..1de7942 100644 --- a/aldryn_django_cms/urls.py +++ b/aldryn_django_cms/urls.py @@ -1,7 +1,5 @@ -# -*- coding: utf-8 -*- - -from django.conf.urls import url, include from django.contrib.sitemaps.views import sitemap +from django.urls import include, re_path from cms.sitemaps import CMSSitemap @@ -9,7 +7,7 @@ urlpatterns = [ - url(r'^admin/~cmscloud-api/check-uninstall/$', check_uninstall_ok, name='cms-check-uninstall'), - url(r'^sitemap.xml$', sitemap, {'sitemaps': {'cmspages': CMSSitemap}}), - url(r'^robots\.txt', include('robots.urls')), + re_path(r'^admin/~cmscloud-api/check-uninstall/$', check_uninstall_ok, name='cms-check-uninstall'), + re_path(r'^sitemap.xml$', sitemap, {'sitemaps': {'cmspages': CMSSitemap}}), + re_path(r'^robots\.txt', include('robots.urls')), ] diff --git a/aldryn_django_cms/urls_i18n.py b/aldryn_django_cms/urls_i18n.py index ee7f72c..7e0e179 100644 --- a/aldryn_django_cms/urls_i18n.py +++ b/aldryn_django_cms/urls_i18n.py @@ -1,11 +1,9 @@ -# -*- coding: utf-8 -*- - -from django.conf.urls import url, include +from django.urls import include, re_path urlpatterns = [ - url(r'^api/~select2/', include('django_select2.urls')), + re_path(r'^api/~select2/', include('django_select2.urls')), # required by aldryn-forms - url(r'^api/~captcha/', include('captcha.urls')), + re_path(r'^api/~captcha/', include('captcha.urls')), ] diff --git a/aldryn_django_cms/utils.py b/aldryn_django_cms/utils.py index c1d6c99..a0ea08e 100644 --- a/aldryn_django_cms/utils.py +++ b/aldryn_django_cms/utils.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- - import inspect - from importlib import import_module @@ -15,11 +12,7 @@ def is_subclass(cls, base_class): def get_classes_from_module(app, module_name, from_base_class=None): module_path = '%s.%s' % (app, module_name) - - try: - module_object = import_module(module_path) - except ImportError: - module_object = None + module_object = import_module(module_path) if not module_object: raise StopIteration diff --git a/aldryn_django_cms/views.py b/aldryn_django_cms/views.py index 2f5e44a..82db28b 100644 --- a/aldryn_django_cms/views.py +++ b/aldryn_django_cms/views.py @@ -1,11 +1,6 @@ -# -*- coding: utf-8 -*- - import json -from django.http import ( - HttpResponse, - HttpResponseBadRequest -) +from django.http import HttpResponse, HttpResponseBadRequest from cms.app_base import CMSApp from cms.models import CMSPlugin, Page @@ -72,7 +67,7 @@ def check_uninstall_ok(request): # will be required in 3.5 new_cms_menu_classes = set(get_classes_from_module(app=app, module_name="cms_menus")) - for menu_class in (old_cms_menu_classes|new_cms_menu_classes): + for menu_class in (old_cms_menu_classes | new_cms_menu_classes): menu = menu_class.__name__ # Only look at menus that are "cms_enabled" cms_enabled = getattr(menu_class, 'cms_enabled', False) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..88229d4 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,27 @@ +[flake8] +max-line-length = 119 +exclude = + *.egg-info, + .eggs, + .git, + .settings, + .tox, + build, + data, + dist, + docs, + *migrations*, + requirements, + tmp + +[isort] +line_length = 79 +skip = manage.py, *migrations*, .tox, .eggs, data +include_trailing_comma = true +multi_line_output = 5 +lines_after_imports = 2 +default_section = THIRDPARTY +sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LOCALFOLDER +known_first_party = aldryn_django_cms +known_cms = cms, menus +known_django = django diff --git a/setup.py b/setup.py index 700de6a..24b674a 100644 --- a/setup.py +++ b/setup.py @@ -1,41 +1,71 @@ -# -*- coding: utf-8 -*- +#!/usr/bin/env python +from setuptools import find_packages, setup -from setuptools import setup, find_packages from aldryn_django_cms import __version__ + +REQUIREMENTS = [ + 'django-cms==4.0.1.dev2', + + 'aldryn-addons', + 'requests', + + # NOTE: django-cms doesn't require this, but many of the addons do. + # If it is used, however, then it must be >=1.0.9 for CMS 3.3+. + 'django-treebeard>=4.0.1', # django-cms + 'djangocms-admin-style', # django-cms + 'django-select2>=6.2', + + # Other common + # ------------ + # TODO: mostly to be split out into other packages + 'aldryn-snake', + 'django-compressor', + 'django-parler', + # Django Sortedm2m 1.3 introduced a regression, that was fixed in 1.3.2 + # See https://github.com/gregmuellegger/django-sortedm2m/issues/80 + 'django-sortedm2m>=1.5.0', + 'django-robots', + 'django-simple-captcha<=0.5.20', + 'lxml', + 'YURL', +] + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Web Environment', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Framework :: Django', + 'Framework :: Django :: 3.2', + 'Framework :: Django :: 4.2', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', +] + + setup( - name="aldryn-django-cms", + name='aldryn-django-cms', version=__version__, - description='An opinionated django CMS setup bundled as an Aldryn Addon', author='Divio AG', author_email='info@divio.ch', - url='https://github.com/aldryn/aldryn-django-cms', + url='https://github.com/divio/aldryn-django-cms', + license='BSD-3-Clause', + description='An opinionated django CMS setup bundled as an Divio Cloud addon', + long_description=open('README.rst').read(), packages=find_packages(), - install_requires=( - 'aldryn-addons', - 'django-cms==4.0.1.dev2', - 'requests', - - # NOTE: django-cms doesn't require this, but many of the addons do. - 'django-treebeard>=4.0.1', # django-cms - 'djangocms-admin-style', # django-cms - 'django-select2>=4.3', - - # Other common - # ------------ - # TODO: mostly to be split out into other packages - 'aldryn-snake', - 'django-compressor', - 'django-parler', - # Django Sortedm2m 1.3 introduced a regression, that was fixed in 1.3.2 - # See https://github.com/gregmuellegger/django-sortedm2m/issues/80 - 'django-sortedm2m>=1.2.2,!=1.3.0,!=1.3.1', - 'django-robots', - 'django-simple-captcha', - 'lxml', - 'YURL', - 'psycopg2', - ), include_package_data=True, zip_safe=False, + install_requires=REQUIREMENTS, + classifiers=CLASSIFIERS, + test_suite='tests.settings.run', ) diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 0000000..11cfbd2 --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,9 @@ +# other requirements +django-app-helper +coverage +isort +flake8 +# needed for the build to work +uwsgi +# requirements from setup.py +django-filer>=1.2.4 diff --git a/tests/settings.py b/tests/settings.py new file mode 100644 index 0000000..ff3cbb6 --- /dev/null +++ b/tests/settings.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +HELPER_SETTINGS = { + 'INSTALLED_APPS': [], + 'SECRET_KEY': 'not-empty', + 'CMS_LANGUAGES': { + 1: [{ + 'code': 'en', + 'name': 'English', + }] + }, + 'LANGUAGE_CODE': 'en', + 'ALLOWED_HOSTS': ['localhost'], +} + + +def run(): + from app_helper import runner + runner.cms('aldryn_django_cms') + + +if __name__ == '__main__': + run() diff --git a/tests/test_migrations.py b/tests/test_migrations.py new file mode 100644 index 0000000..29c4a94 --- /dev/null +++ b/tests/test_migrations.py @@ -0,0 +1,30 @@ +# original from +# http://tech.octopus.energy/news/2016/01/21/testing-for-missing-migrations-in-django.html +from io import StringIO + +from django.core.management import call_command +from django.test import TestCase, override_settings + + +class MigrationTestCase(TestCase): + + @override_settings(MIGRATION_MODULES={}) + def test_for_missing_migrations(self): + output = StringIO() + options = { + 'interactive': False, + 'dry_run': True, + 'stdout': output, + 'check_changes': True, + } + + try: + call_command('makemigrations', **options) + except SystemExit as e: + status_code = str(e) + else: + # the "no changes" exit code is 0 + status_code = '0' + + if status_code == '1': + self.fail('There are missing migrations:\n {}'.format(output.getvalue()))