From c4311d82afc1bb44566c6e612b09c4ecad1af643 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 3 Apr 2019 12:14:19 +0200 Subject: [PATCH] Support for Django up to 2.2. `textile` and `pipeline` dependencies are now in extras. Deprecated `utils.urls.i18n_patterns` and `middleware.URLLocaleMiddleware`, as Django 1.10 adds `prefix_default_language` parameter to `i18n_patterns`. Removed `auth_backends.AttrCASBackend`; use `django-cas-ng` instead. Added this changelog. --- CHANGELOG.md | 199 +++++++++++++++++++++ fnpdjango/auth_backends.py | 26 --- fnpdjango/middleware.py | 65 ++++--- fnpdjango/templates/fnpdjango/annoy.html | 9 +- fnpdjango/templatetags/fnp_lang.py | 7 +- fnpdjango/utils/urls.py | 72 ++++---- runtests.py | 9 +- setup.py | 13 +- tests/tests/__init__.py | 1 + tests/tests/test_templatetags_fnp_annoy.py | 22 +++ tox.ini | 6 +- 11 files changed, 338 insertions(+), 91 deletions(-) create mode 100644 CHANGELOG.md delete mode 100644 fnpdjango/auth_backends.py create mode 100644 tests/tests/test_templatetags_fnp_annoy.py diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7c73ba6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,199 @@ +# Change Log + +This document records all notable changes to fnpdjango. + + +## 0.4 (2019-04-03) + +- Support for Django up to 2.2. +- `textile` and `pipeline` dependencies are now in extras. +- Deprecated `utils.urls.i18n_patterns` and `middleware.URLLocaleMiddleware`, + as Django 1.10 adds `prefix_default_language` parameter to `i18n_patterns`. +- Removed `auth_backends.AttrCASBackend`; use `django-cas-ng` instead. +- Added this changelog. + + +## 0.3 (2019-02-15) + +- Support for Django 1.11. +- Dropped support for Python 2.6, 3.2, 3.3 +- Removed `prefix` parameter from `utilsurls.i18n_patterns`. + + +## 0.2.8 (2018-07-10) + +- Restored `utils.text.char_map`, removed in 0.2 with `slughifi`. + + +## 0.2.7 (2018-01-22) + +- Enabled `auto_link` in `utils.text.textilepl.textile_restricted_pl`. + + +## 0.2.6 (2017-07-25) + +- Added `utils.fields.TextfileField`. + + +## 0.2.4 (2017-04-05) + +- Support for Django 1.10 +- Removed nk.pl from share icons. +- Updated textile. + + +## 0.2.3 (2017-02-14) + +- Fixed import for Django 1.9 + + +## 0.2.2 (2016-11-08) + +- Fixed bad HTTP 404 in `middleware.URLLocaleMiddleware`. + + +## 0.2.1 (2016-01-04) + +- Test with Django up to 1.9. + + +## 0.2 (2014-09-30) + +- Removed `utils.text.slughifi`; use `python-slugify` instead. +- Removed deployment scripts to another package (`fnpdeploy`). +- Added tests. + + +## 0.1.19-1 (2014-09-01) + +- Pinned textile version. + + +## 0.1.19 (2014-06-09) + +- `auth_backends.AttrCASBackend`: Save user instance only when necessary. +- `deploy`: Added `migrate_fake` option. +- `deploy`: Added root `manage.py` helper script. + + +## 0.1.18 (2014-03-31) + +- Added `templatetags.fnp_annoy`. + + +## 0.1.17 (2014-03-27) + +- Added `auth_backends.AttrCASBackend`. + + +## 0.1.16 (2014-02-25) + +- Added `utils.pipeline_storage.GzipPipelineCachedStorage`. + + +## 0.1.15 (2014-02-14) + +- Added `storage.BofhFileSystemStorage`. + + +## 0.1.14 (2014-01-14) + +- `deploy`: Fixed gunicorn sample upload when `django_root_path` not set. + + +## 0.1.13 (2014-01-14) + +- Enable styling language switcher link depending on the destination language. + + +## 0.1.12 (2014-01-02) + +- `deploy`: Added git hash to relase name. + + +## 0.1.11 (2013-12-30) + +- Support Django 1.6 +- Minor fixes in deployment and bootstrap scripts. + + +## 0.1.10 (2013-12-12) + +- `deploy`: Added `skip_collect_static` option. + + +## 0.1.9.1 (2013-12-06) + +- Quick fix for textile. + + +## 0.1.9 (2013-12-06) + +- Added `templatetags.fnp_markup.textile_en` and `textile_restricted_en`. + + +## 0.1.8 (2013-11-19) + +- Fixed unicode check in slughifi. +- Fixes for deployment and bootstrap scripts. + + +# 0.1.7 (2013-07-04) + +- Fix packaging for `makecontribmessages` command. + +Changes in `deploy`: +- Added `Command` task. +- Added `pre_collectstatic` hook. +- Added `django_root_path` and `localsettings_dst_path` options. +- Auto-install DB requirements. +- Made `setup` idempotent. +- Upgrade `git-archive-all.sh` script. +- Set `SECRET_KEY` on setup. +- Various minor fixes. + + +## 0.1.6 (2013-03-20) +- Support for Django 1.5 + + +## 0.1.5-1 (2013-02-22) + +- Quick fix for previous page link in prevnext. + + +## 0.1.5 (2013-02-22) + +- Made prevnext respect current GET parameters. +- Added a management command for localizing contrib apps. +- Fixed deployment sudo problem. + + +## 0.1.4 (2013-01-10) + +- Added tQ function for filtering translated fields. + + +## 0.1.3 (2013-01-09) + +- Fixedd `get_here_url`. +- Nicer project starter. +- Fixed deployment scripts. + + +## 0.1.2 (2012-11-30) + +- Added app settings. +- Fixed deployment scripts. +- Minor fixes. + + +## 0.1.1 (2012-11-22) + +- Added deployment scripts. +- Minor fixes. + + +## 0.1 (2012-11-05) + +- Initial release. diff --git a/fnpdjango/auth_backends.py b/fnpdjango/auth_backends.py deleted file mode 100644 index 7a89c1a..0000000 --- a/fnpdjango/auth_backends.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.conf import settings -from django_cas.backends import CASBackend - -attr_map = getattr(settings, 'CAS_USER_ATTRS_MAP', { - 'email': 'email', - 'firstname': 'first_name', - 'lastname': 'last_name', -}) - -class AttrCASBackend(CASBackend): - def authenticate(self, ticket, service, request): - user = super(AttrCASBackend, self).authenticate(ticket, service, request) - dirty = False - for attr, value in request.session.get('attributes', {}).items(): - try: - local_attr = attr_map[attr] - except KeyError: - pass - else: - if getattr(user, local_attr, None) != value: - setattr(user, local_attr, value) - dirty = True - if dirty: - user.save() - return user - diff --git a/fnpdjango/middleware.py b/fnpdjango/middleware.py index adf0dc8..734e878 100644 --- a/fnpdjango/middleware.py +++ b/fnpdjango/middleware.py @@ -1,10 +1,48 @@ -from django.utils import translation -from django.conf import settings -from django.http import Http404 from . import app_settings +try: + # Django >= 1.10 + from django.utils.deprecation import MiddlewareMixin +except ImportError: + # Django <= 1.9 + MiddlewareMixin = object -class SetRemoteAddrFromXRealIP(object): + from django.conf import settings + from django.http import Http404 + from django.utils import translation + + class URLLocaleMiddleware(MiddlewareMixin): + """Decides which translation to use, based on path only.""" + def process_request(self, request): + language = translation.get_language_from_path(request.path_info) + if language: + translation.activate(language) + request.LANGUAGE_CODE = translation.get_language() + if language == settings.LANGUAGE_CODE: + raise Http404 + + def process_response(self, request, response): + language = translation.get_language() + translation.deactivate() + if 'Content-Language' not in response: + response['Content-Language'] = language + return response +else: + # Django >= 1.10 + import warnings + from django.middleware.locale import LocaleMiddleware + + class URLLocaleMiddleware(LocaleMiddleware): + def __init__(self, *args, **kwargs): + warnings.warn( + "As of Django 1.10, fnpdjango.middleware.URLLocaleMiddleware " + "is deprecated in favor of " + "django.middleware.locale.LocaleMiddleware.", + DeprecationWarning) + super(URLLocaleMiddleware, self).__init__(*args, **kwargs) + + +class SetRemoteAddrFromXRealIP(MiddlewareMixin): """Sets REMOTE_ADDR from the X-Real-IP header, as set by Nginx.""" def process_request(self, request): if app_settings.REALIP: @@ -13,22 +51,3 @@ class SetRemoteAddrFromXRealIP(object): except KeyError: pass return None - - -class URLLocaleMiddleware(object): - """Decides which translation to use, based on path only.""" - - def process_request(self, request): - language = translation.get_language_from_path(request.path_info) - if language: - translation.activate(language) - request.LANGUAGE_CODE = translation.get_language() - if language == settings.LANGUAGE_CODE: - raise Http404 - - def process_response(self, request, response): - language = translation.get_language() - translation.deactivate() - if 'Content-Language' not in response: - response['Content-Language'] = language - return response diff --git a/fnpdjango/templates/fnpdjango/annoy.html b/fnpdjango/templates/fnpdjango/annoy.html index bfec223..996212c 100644 --- a/fnpdjango/templates/fnpdjango/annoy.html +++ b/fnpdjango/templates/fnpdjango/annoy.html @@ -1,16 +1,15 @@ -{% load static from staticfiles %} -1% +{% load static from static %} +1%
- + Logo akcji 1% -

Droga użytkowniczko, drogi użytkowniku!

Fundacja Nowoczesna Polska to organizacja pożytku publicznego działająca na rzecz wolności korzystania z dóbr kultury. Wesprzyj nasze działania, przeznaczając na nie 1% swojego podatku. Możesz to zrobić, wpisując w zeznaniu podatkowym numer KRS 0000070056.

-

Dowiedz się więcej

+

Dowiedz się więcej

x
diff --git a/fnpdjango/templatetags/fnp_lang.py b/fnpdjango/templatetags/fnp_lang.py index 5f7ac24..dd6c339 100644 --- a/fnpdjango/templatetags/fnp_lang.py +++ b/fnpdjango/templatetags/fnp_lang.py @@ -1,5 +1,10 @@ from django.conf import settings -from django.core.urlresolvers import resolve, reverse, Resolver404 + +try: + from django.urls import resolve, reverse, Resolver404 +except ImportError: + from django.core.urlresolvers import resolve, reverse, Resolver404 + from django import template from django.utils import translation from ..utils.views import get_current_object diff --git a/fnpdjango/utils/urls.py b/fnpdjango/utils/urls.py index a493c97..4e9916f 100644 --- a/fnpdjango/utils/urls.py +++ b/fnpdjango/utils/urls.py @@ -2,38 +2,50 @@ Utilities for urlconfs. """ -import re -from django.conf import settings -from django.core.urlresolvers import LocaleRegexURLResolver -from django.utils.translation import get_language +import django +if django.VERSION >= (1, 10): + import warnings + from django.conf.urls.i18n import i18n_patterns as django_i18n_patterns + def i18n_patterns(*args): + warnings.warn( + "As of Django 1.10, fnpdjango.utils.urls.i18n_patterns " + "is deprecated in favor of directly using " + "django.urls.i18n_patterns(prefix_default_language=False).", + DeprecationWarning) + return django_i18n_patterns(*args, prefix_default_language=False) -class MyLocaleRegexURLResolver(LocaleRegexURLResolver): - """ - A URL resolver that always matches the active language code as URL prefix. +else: + # Django <= 1.9 + import re + from django.conf import settings + from django.core.urlresolvers import LocaleRegexURLResolver + from django.utils.translation import get_language - Rather than taking a regex argument, we just override the ``regex`` - function to always return the active language-code as regex. - """ - @property - def regex(self): - language_code = get_language() - if language_code == settings.LANGUAGE_CODE: - return re.compile('') - if language_code not in self._regex_dict: - regex_compiled = re.compile('^%s/' % language_code, re.UNICODE) - self._regex_dict[language_code] = regex_compiled - return self._regex_dict[language_code] + class MyLocaleRegexURLResolver(LocaleRegexURLResolver): + """ + A URL resolver that always matches the active language code as URL prefix. + Rather than taking a regex argument, we just override the ``regex`` + function to always return the active language-code as regex. + """ + @property + def regex(self): + language_code = get_language() + if language_code == settings.LANGUAGE_CODE: + return re.compile('') + if language_code not in self._regex_dict: + regex_compiled = re.compile('^%s/' % language_code, re.UNICODE) + self._regex_dict[language_code] = regex_compiled + return self._regex_dict[language_code] -def i18n_patterns(*args): - """ - Adds the language code prefix to every URL pattern within this - function. This may only be used in the root URLconf, not in an included - URLconf. - - """ - pattern_list = list(args) - if not settings.USE_I18N: - return pattern_list - return pattern_list + [MyLocaleRegexURLResolver(pattern_list)] + def i18n_patterns(*args): + """ + Adds the language code prefix to every URL pattern within this + function. This may only be used in the root URLconf, not in an included + URLconf. + """ + pattern_list = list(args) + if not settings.USE_I18N: + return pattern_list + return pattern_list + [MyLocaleRegexURLResolver(pattern_list)] diff --git a/runtests.py b/runtests.py index 3f8dd95..28648cf 100644 --- a/runtests.py +++ b/runtests.py @@ -41,7 +41,13 @@ if not settings.configured and not os.environ.get('DJANGO_SETTINGS_MODULE'): ], LANGUAGE_CODE='pl', MEDIA_ROOT=media_root, - MIDDLEWARE_CLASSES=[ + STATIC_URL='/static/', + MIDDLEWARE_CLASSES=[ # Django <= 1.9 + 'django.middleware.common.CommonMiddleware', + 'fnpdjango.middleware.URLLocaleMiddleware', + 'fnpdjango.middleware.SetRemoteAddrFromXRealIP', + ], + MIDDLEWARE=[ 'django.middleware.common.CommonMiddleware', 'fnpdjango.middleware.URLLocaleMiddleware', 'fnpdjango.middleware.SetRemoteAddrFromXRealIP', @@ -51,6 +57,7 @@ if not settings.configured and not os.environ.get('DJANGO_SETTINGS_MODULE'): TEMPLATES=[ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, }, ], TEST_LAZY_UGETTEXT_LAZY=_("Lazy setting."), diff --git a/setup.py b/setup.py index adb30aa..c0775b7 100755 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def whole_trees(package_dir, paths): setup( name='fnpdjango', - version='0.3', + version='0.4', author='Radek Czajka', author_email='radekczajka@nowoczesnapolska.org.pl', url='', @@ -33,9 +33,16 @@ setup( 'fnpdjango.management.commands': ['babel.cfg'], }, install_requires=[ - 'Django>=1.4,<2.0', - 'textile==2.3.16', + 'Django>=1.4,<2.3', ], + extras_require={ + 'textile': [ + 'textile==2.3.16', + ], + 'pipeline': [ + 'pipeline', + ], + }, license='LICENSE', description='.', long_description="", diff --git a/tests/tests/__init__.py b/tests/tests/__init__.py index 468aae5..7801a8c 100644 --- a/tests/tests/__init__.py +++ b/tests/tests/__init__.py @@ -10,6 +10,7 @@ test_* modules by itself. """ from .test_middleware import * from .test_storage import * +from .test_templatetags_fnp_annoy import * from .test_templatetags_fnp_markup import * from .test_templatetags_macros import * from .test_utils_settings import * diff --git a/tests/tests/test_templatetags_fnp_annoy.py b/tests/tests/test_templatetags_fnp_annoy.py new file mode 100644 index 0000000..8ed80b1 --- /dev/null +++ b/tests/tests/test_templatetags_fnp_annoy.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See README.md for more information. +# +from __future__ import unicode_literals + +from django.test import TestCase +from django.test.utils import override_settings + + +class TemplatetagsFNPAnnoyTestCase(TestCase): + + def test_annoy(self): + from fnpdjango.templatetags import fnp_annoy + self.assertEqual( + fnp_annoy.annoy(), + '') + with override_settings(FNP_ANNOY=True): + self.assertTrue( + 'https://nowoczesnapolska.org.pl/pomoz-nam/1-procent/' + in fnp_annoy.annoy() + ) diff --git a/tox.ini b/tox.ini index 2175e7c..5e71cfb 100644 --- a/tox.ini +++ b/tox.ini @@ -7,8 +7,8 @@ envlist=clear, d17-py{27,34}, d{18,19,110}-py{27,34,35}, d111-py{27,34,35,36,37}, - #d20-py{34,35,36,37}, - #d21-py{35,36,37}, + d20-py{34,35,36,37}, + d{21,22}-py{35,36,37}, stats [testenv] @@ -25,6 +25,8 @@ deps= d20: Django>=2.0,<2.1 d21: Django>=2.1,<2.2 coverage +extras= + textile [testenv:clear] basepython=python3.4 -- 2.20.1