From f9fcb9d9a34a584a5dc7c75b44e3afa356d6e3e3 Mon Sep 17 00:00:00 2001
From: Mika Ivarsson <13712961+Mojken@users.noreply.github.com>
Date: Wed, 30 Mar 2022 17:43:15 +0200
Subject: [PATCH 01/42] Introduce and run pre-commit
---
.gitignore | 2 +-
.pre-commit-config.yaml | 81 +++++
README.md | 6 +-
djedi-react/.npm-upgrade.json | 2 +-
djedi-react/test/Node.test.js | 4 +-
djedi/__init__.py | 58 ++--
djedi/admin/__init__.py | 31 +-
djedi/admin/api.py | 56 ++--
djedi/admin/cms.py | 11 +-
djedi/admin/mixins.py | 22 +-
djedi/admin/urls.py | 18 +-
djedi/auth/__init__.py | 12 +-
djedi/backends/django/cache/backend.py | 35 +-
djedi/backends/django/db/backend.py | 40 ++-
djedi/backends/django/db/models.py | 4 +-
djedi/compat.py | 112 ++++---
djedi/middleware/__init__.py | 6 +-
djedi/middleware/admin.py | 3 +-
djedi/middleware/mixins.py | 63 ++--
djedi/middleware/translation.py | 3 +-
djedi/migrations/0001_initial.py | 34 +-
djedi/migrations/0002_auto_20190722_1447.py | 6 +-
djedi/models.py | 4 +-
djedi/plugins/form.py | 21 +-
djedi/plugins/img.py | 94 +++---
djedi/rest/api.py | 19 +-
djedi/rest/urls.py | 8 +-
djedi/south_migrations/0001_initial.py | 90 +++--
.../djedi/plugins/img/js/jquery.Jcrop.min.js | 2 +-
.../fonts/fontawesome-webfont.svg | 2 +-
.../base/fonts/Roboto-Black-webfont.svg | 2 +-
.../base/fonts/Roboto-BlackItalic-webfont.svg | 2 +-
.../themes/base/fonts/Roboto-Bold-webfont.svg | 2 +-
.../fonts/Roboto-BoldCondensed-webfont.svg | 2 +-
.../Roboto-BoldCondensedItalic-webfont.svg | 2 +-
.../base/fonts/Roboto-BoldItalic-webfont.svg | 2 +-
.../base/fonts/Roboto-Condensed-webfont.svg | 2 +-
.../fonts/Roboto-CondensedItalic-webfont.svg | 2 +-
.../base/fonts/Roboto-Italic-webfont.svg | 2 +-
.../base/fonts/Roboto-Light-webfont.svg | 2 +-
.../base/fonts/Roboto-LightItalic-webfont.svg | 2 +-
.../base/fonts/Roboto-Medium-webfont.svg | 2 +-
.../fonts/Roboto-MediumItalic-webfont.svg | 2 +-
.../base/fonts/Roboto-Regular-webfont.svg | 2 +-
.../themes/base/fonts/Roboto-Thin-webfont.svg | 2 +-
.../base/fonts/Roboto-ThinItalic-webfont.svg | 2 +-
.../static/djedi/themes/base/fonts/djedi.svg | 2 +-
.../vendor/bootstrap/css/bootstrap-theme.css | 2 +-
.../bootstrap/css/bootstrap-theme.min.css | 2 +-
.../djedi/vendor/bootstrap/css/bootstrap.css | 2 +-
.../vendor/bootstrap/css/bootstrap.min.css | 2 +-
.../fonts/glyphicons-halflings-regular.svg | 2 +-
.../vendor/bootstrap/less/dropdowns.less | 1 -
.../djedi/vendor/chosen/chosen.jquery.min.js | 2 +-
.../static/djedi/vendor/chosen/chosen.min.css | 2 +-
.../vendor/jquery.form/jquery.form.min.js | 2 +-
djedi/templatetags/djedi_admin.py | 16 +-
djedi/templatetags/djedi_tags.py | 37 ++-
djedi/templatetags/template.py | 30 +-
djedi/tests/base.py | 63 ++--
djedi/tests/compat.py | 5 +-
djedi/tests/test_admin.py | 52 +--
djedi/tests/test_cache.py | 9 +-
djedi/tests/test_rest.py | 309 ++++++++++--------
djedi/tests/test_settings.py | 15 +-
djedi/tests/test_templatetags.py | 132 ++++----
djedi/tests/urls.py | 6 +-
djedi/urls.py | 7 +-
djedi/utils/encoding.py | 7 +-
docs/_static/djedi-landscape.svg | 2 +-
docs/_static/djedi-portrait.svg | 2 +-
docs/conf.py | 145 ++++----
docs/index.rst | 4 +-
docs/installation.rst | 14 +-
docs/plugins.rst | 11 +-
docs/settings.rst | 39 ++-
runtests.py | 140 ++++----
setup.cfg | 5 +-
setup.py | 96 +++---
79 files changed, 1129 insertions(+), 917 deletions(-)
create mode 100644 .pre-commit-config.yaml
diff --git a/.gitignore b/.gitignore
index 302584e6..d6350be7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,4 +22,4 @@ example/db.sqlite3
*~
\#*\#
.#*.*
-*_flymake*
\ No newline at end of file
+*_flymake*
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..25e9aafa
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,81 @@
+default_language_version:
+ python: python3.10
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.1.0
+ hooks:
+ - id: check-case-conflict
+ - id: check-merge-conflict
+ - id: end-of-file-fixer
+ - id: trailing-whitespace
+ - id: debug-statements
+ - id: detect-private-key
+ - repo: https://github.com/asottile/pyupgrade
+ rev: v2.31.0
+ hooks:
+ - id: pyupgrade
+ args:
+ - --py37-plus
+ - repo: https://github.com/myint/autoflake
+ rev: v1.4
+ hooks:
+ - id: autoflake
+ args:
+ - --in-place
+ - --remove-all-unused-imports
+ - --ignore-init-module-imports
+ - repo: https://github.com/pycqa/isort
+ rev: 5.10.1
+ hooks:
+ - id: isort
+ - repo: https://github.com/psf/black
+ rev: 22.3.0
+ hooks:
+ - id: black
+ - repo: https://github.com/asottile/blacken-docs
+ rev: v1.12.1
+ hooks:
+ - id: blacken-docs
+ additional_dependencies: [black==22.1.0]
+ - repo: https://gitlab.com/pycqa/flake8
+ rev: 3.9.2
+ hooks:
+ - id: flake8
+ additional_dependencies:
+ - flake8-bugbear
+ - flake8-comprehensions
+ - flake8-tidy-imports
+ - repo: https://github.com/sirosen/check-jsonschema
+ rev: 0.11.0
+ hooks:
+ - id: check-github-workflows
+# - repo: https://github.com/mgedmin/check-manifest
+# rev: "0.47"
+# hooks:
+# - id: check-manifest
+# # See https://github.com/mgedmin/check-manifest/issues/141
+# args: ["--no-build-isolation"]
+# Unsure how to solve this failing
+
+exclude: |
+ (?x)(
+ /(
+ \.eggs
+ | \.git
+ | \.hg
+ | \.mypy_cache
+ | \.pytest_cache
+ | \.nox
+ | \.tox
+ | \.venv
+ | _build
+ | buck-out
+ | build
+ | dist
+ )/
+ | ^(
+ example
+ | scripts
+ | tests/project/files
+ )/
+ )
diff --git a/README.md b/README.md
index 96cc0d0d..f2dc90f5 100644
--- a/README.md
+++ b/README.md
@@ -28,11 +28,11 @@ Example settings for Django 2.0:
INSTALLED_APPS = (
# ...
- 'djedi',
+ "djedi",
)
MIDDLEWARE = [
- 'djedi.middleware.translation.DjediTranslationMiddleware',
+ "djedi.middleware.translation.DjediTranslationMiddleware",
# ...
]
```
@@ -49,7 +49,7 @@ $ django-admin.py migrate djedi
# urls.py
urlpatterns = [
- path('admin/', admin.site.urls),
+ path("admin/", admin.site.urls),
]
```
diff --git a/djedi-react/.npm-upgrade.json b/djedi-react/.npm-upgrade.json
index ce8e0899..5e944594 100644
--- a/djedi-react/.npm-upgrade.json
+++ b/djedi-react/.npm-upgrade.json
@@ -9,4 +9,4 @@
"reason": "Not compatible with newer versions"
}
}
-}
\ No newline at end of file
+}
diff --git a/djedi-react/test/Node.test.js b/djedi-react/test/Node.test.js
index 633ce081..903b194a 100644
--- a/djedi-react/test/Node.test.js
+++ b/djedi-react/test/Node.test.js
@@ -319,7 +319,7 @@ test("it handles nodes with null value in response", async () => {
-
+
`);
});
@@ -773,7 +773,7 @@ Network error",
-
+
diff --git a/djedi/__init__.py b/djedi/__init__.py
index 073c180f..81c35d34 100644
--- a/djedi/__init__.py
+++ b/djedi/__init__.py
@@ -1,5 +1,4 @@
-# coding=utf-8
-VERSION = (1, 3, 3, 'final', 0)
+VERSION = (1, 3, 3, "final", 0)
def get_version(version=None):
@@ -7,7 +6,7 @@ def get_version(version=None):
if version is None:
version = VERSION
assert len(version) == 5
- assert version[3] in ('alpha', 'beta', 'rc', 'final')
+ assert version[3] in ("alpha", "beta", "rc", "final")
# Now build the two parts of the version number:
# main = X.Y[.Z]
@@ -15,11 +14,11 @@ def get_version(version=None):
# | {a|b|c}N - for alpha, beta and rc releases
parts = 2 if version[2] == 0 else 3
- main = '.'.join(str(x) for x in version[:parts])
+ main = ".".join(str(x) for x in version[:parts])
- sub = ''
- if version[3] != 'final':
- mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
+ sub = ""
+ if version[3] != "final":
+ mapping = {"alpha": "a", "beta": "b", "rc": "c"}
sub = mapping[version[3]] + str(version[4])
return main + sub
@@ -30,33 +29,44 @@ def get_version(version=None):
def configure():
from django.conf import settings as django_settings
+
from cio.conf import settings
# Djedi default config
- config = dict(
- ENVIRONMENT={
- 'default': {
- 'i18n': django_settings.LANGUAGE_CODE,
- 'l10n': getattr(django_settings, 'ROOT_URLCONF', 'local').split('.', 1)[0],
- 'g11n': 'global'
+ config = {
+ "ENVIRONMENT": {
+ "default": {
+ "i18n": django_settings.LANGUAGE_CODE,
+ "l10n": getattr(django_settings, "ROOT_URLCONF", "local").split(".", 1)[
+ 0
+ ],
+ "g11n": "global",
}
},
- CACHE='djedi.backends.django.cache.Backend',
- STORAGE='djedi.backends.django.db.Backend',
- PLUGINS=[
- 'cio.plugins.txt.TextPlugin',
- 'cio.plugins.md.MarkdownPlugin',
- 'djedi.plugins.img.ImagePlugin'
+ "CACHE": "djedi.backends.django.cache.Backend",
+ "STORAGE": "djedi.backends.django.db.Backend",
+ "PLUGINS": [
+ "cio.plugins.txt.TextPlugin",
+ "cio.plugins.md.MarkdownPlugin",
+ "djedi.plugins.img.ImagePlugin",
],
- THEME='darth'
- )
+ "THEME": "darth",
+ }
# Update config with global djedi django settings
- config.update(getattr(django_settings, 'DJEDI', {}))
+ config.update(getattr(django_settings, "DJEDI", {}))
# Overwrite config with prefixed variables from django settings
- for setting in ('ENVIRONMENT', 'CACHE', 'STORAGE', 'PIPELINE', 'PLUGINS', 'THEME', 'XSS_DOMAIN'):
- conf = getattr(django_settings, 'DJEDI_%s' % setting, None)
+ for setting in (
+ "ENVIRONMENT",
+ "CACHE",
+ "STORAGE",
+ "PIPELINE",
+ "PLUGINS",
+ "THEME",
+ "XSS_DOMAIN",
+ ):
+ conf = getattr(django_settings, "DJEDI_%s" % setting, None)
if conf is not None:
config[setting] = conf
diff --git a/djedi/admin/__init__.py b/djedi/admin/__init__.py
index c259f3a9..094c2b2a 100644
--- a/djedi/admin/__init__.py
+++ b/djedi/admin/__init__.py
@@ -1,23 +1,32 @@
from django.contrib import admin
from django.db.models import Model
from django.template.defaultfilters import pluralize
+
from djedi.admin import cms
def register(admin_class):
name = admin_class.verbose_name
- name_plural = getattr(admin_class, 'verbose_name_plural', pluralize(name))
+ name_plural = getattr(admin_class, "verbose_name_plural", pluralize(name))
- model = type(name, (Model,), {
- '__module__': __name__,
- 'Meta': type('Meta', (object,), dict(
- managed=False,
- abstract=True,
- app_label='djedi',
- verbose_name=name,
- verbose_name_plural=name_plural
- ))
- })
+ model = type(
+ name,
+ (Model,),
+ {
+ "__module__": __name__,
+ "Meta": type(
+ "Meta",
+ (object,),
+ {
+ "managed": False,
+ "abstract": True,
+ "app_label": "djedi",
+ "verbose_name": name,
+ "verbose_name_plural": name_plural,
+ },
+ ),
+ },
+ )
admin.site._registry[model] = admin_class(model, admin.site)
diff --git a/djedi/admin/api.py b/djedi/admin/api.py
index 223853fb..c45dc28c 100644
--- a/djedi/admin/api.py
+++ b/djedi/admin/api.py
@@ -1,8 +1,7 @@
from collections import defaultdict
-from djedi.plugins.base import DjediPlugin
from django.core.exceptions import PermissionDenied
-from django.http import HttpResponse, Http404, HttpResponseBadRequest
+from django.http import Http404, HttpResponse, HttpResponseBadRequest
from django.utils.http import urlunquote
from django.views.decorators.cache import never_cache
from django.views.decorators.clickjacking import xframe_options_exempt
@@ -13,22 +12,22 @@
from cio.plugins import plugins
from cio.plugins.exceptions import UnknownPlugin
from cio.utils.uri import URI
+from djedi.plugins.base import DjediPlugin
-from .exceptions import InvalidNodeData
-from .mixins import JSONResponseMixin, DjediContextMixin
-from ..compat import TemplateResponse
from .. import auth
+from ..compat import TemplateResponse
+from .exceptions import InvalidNodeData
+from .mixins import DjediContextMixin, JSONResponseMixin
class APIView(View):
-
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
if not auth.has_permission(request):
raise PermissionDenied
try:
- return super(APIView, self).dispatch(request, *args, **kwargs)
+ return super().dispatch(request, *args, **kwargs)
except Http404:
raise
except Exception as e:
@@ -50,17 +49,19 @@ def get_post_data(self, request):
if isinstance(value, list) and len(value) <= 1:
value = value[0] if value else None
- prefix, _, field = param.partition('[')
+ prefix, _, field = param.partition("[")
if field:
field = field[:-1]
try:
data[prefix][field] = value
except TypeError:
- raise InvalidNodeData('Got both reserved parameter "data" and plugin specific parameters.')
+ raise InvalidNodeData(
+ 'Got both reserved parameter "data" and plugin specific parameters.'
+ )
else:
data[prefix] = value
- return data['data'], data['meta']
+ return data["data"], data["meta"]
def decode_uri(self, uri):
decoded = urlunquote(uri)
@@ -71,12 +72,11 @@ def decode_uri(self, uri):
return decoded
- def render_to_response(self, content=u''):
+ def render_to_response(self, content=""):
return HttpResponse(content)
class NodeApi(JSONResponseMixin, APIView):
-
@never_cache
def get(self, request, uri):
"""
@@ -91,10 +91,7 @@ def get(self, request, uri):
if node.content is None:
raise Http404
- return self.render_to_json({
- 'uri': node.uri,
- 'content': node.content
- })
+ return self.render_to_json({"uri": node.uri, "content": node.content})
def post(self, request, uri):
"""
@@ -105,7 +102,7 @@ def post(self, request, uri):
"""
uri = self.decode_uri(uri)
data, meta = self.get_post_data(request)
- meta['author'] = auth.get_username(request)
+ meta["author"] = auth.get_username(request)
node = cio.set(uri, data, publish=False, **meta)
return self.render_to_json(node)
@@ -123,7 +120,6 @@ def delete(self, request, uri):
class PublishApi(JSONResponseMixin, APIView):
-
def put(self, request, uri):
"""
Publish versioned uri.
@@ -141,7 +137,6 @@ def put(self, request, uri):
class RevisionsApi(JSONResponseMixin, APIView):
-
def get(self, request, uri):
"""
List uri revisions.
@@ -151,12 +146,13 @@ def get(self, request, uri):
"""
uri = self.decode_uri(uri)
revisions = cio.revisions(uri)
- revisions = [list(revision) for revision in revisions] # Convert tuples to lists
+ revisions = [
+ list(revision) for revision in revisions
+ ] # Convert tuples to lists
return self.render_to_json(revisions)
class LoadApi(JSONResponseMixin, APIView):
-
@never_cache
def get(self, request, uri):
"""
@@ -171,7 +167,6 @@ def get(self, request, uri):
class RenderApi(APIView):
-
def post(self, request, ext):
"""
Render data for plugin and return text response.
@@ -188,7 +183,6 @@ def post(self, request, ext):
class NodeEditor(JSONResponseMixin, DjediContextMixin, APIView):
-
@never_cache
@xframe_options_exempt
def get(self, request, uri):
@@ -210,11 +204,11 @@ def get(self, request, uri):
def post(self, request, uri):
uri = self.decode_uri(uri)
data, meta = self.get_post_data(request)
- meta['author'] = auth.get_username(request)
+ meta["author"] = auth.get_username(request)
node = cio.set(uri, data, publish=False, **meta)
context = cio.load(node.uri)
- context['content'] = node.content
+ context["content"] = node.content
if request.is_ajax():
return self.render_to_json(context)
@@ -222,7 +216,11 @@ def post(self, request, uri):
return self.render_plugin(request, context)
def render_plugin(self, request, context):
- return TemplateResponse(request, [
- 'djedi/plugins/%s/editor.html' % context['uri'].ext,
- 'djedi/plugins/base/editor.html'
- ], self.get_context_data(**context))
+ return TemplateResponse(
+ request,
+ [
+ "djedi/plugins/%s/editor.html" % context["uri"].ext,
+ "djedi/plugins/base/editor.html",
+ ],
+ self.get_context_data(**context),
+ )
diff --git a/djedi/admin/cms.py b/djedi/admin/cms.py
index 61749164..e676d901 100644
--- a/djedi/admin/cms.py
+++ b/djedi/admin/cms.py
@@ -10,13 +10,15 @@
class Admin(ModelAdmin):
- verbose_name = 'CMS'
+ verbose_name = "CMS"
verbose_name_plural = verbose_name
def get_urls(self):
return patterns(
- url(r'^', include('djedi.admin.urls', namespace='djedi')),
- url(r'', lambda: None, name='djedi_cms_changelist') # Placeholder to show change link to CMS in admin
+ url(r"^", include("djedi.admin.urls", namespace="djedi")),
+ url(
+ r"", lambda: None, name="djedi_cms_changelist"
+ ), # Placeholder to show change link to CMS in admin
)
def has_change_permission(self, request, obj=None):
@@ -35,10 +37,9 @@ def has_module_permission(self, request):
class DjediCMS(DjediContextMixin, View):
-
@xframe_options_exempt
def get(self, request):
if has_permission(request):
- return render(request, 'djedi/cms/cms.html', self.get_context_data())
+ return render(request, "djedi/cms/cms.html", self.get_context_data())
else:
raise PermissionDenied
diff --git a/djedi/admin/mixins.py b/djedi/admin/mixins.py
index e10a4cfb..71c0af05 100644
--- a/djedi/admin/mixins.py
+++ b/djedi/admin/mixins.py
@@ -1,26 +1,27 @@
import simplejson as json
from django.conf import settings as django_settings
from django.http import HttpResponse
-from cio.conf import settings
+
import djedi
+from cio.conf import settings
# TODO: Switch simplejson to ujson or other?
-class JSONResponseMixin(object):
+class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
+
response_class = HttpResponse
def render_to_json(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
- response_kwargs['content_type'] = 'application/json'
+ response_kwargs["content_type"] = "application/json"
return self.response_class(
- self.convert_context_to_json(context),
- **response_kwargs
+ self.convert_context_to_json(context), **response_kwargs
)
def convert_context_to_json(self, context):
@@ -28,15 +29,14 @@ def convert_context_to_json(self, context):
return json.dumps(context, indent=4, for_json=True)
-class DjediContextMixin(object):
-
+class DjediContextMixin:
def get_context_data(self, **context):
theme = settings.THEME
- if '/' not in theme:
- theme = '{static}djedi/themes/{theme}/theme.css'.format(static=django_settings.STATIC_URL, theme=theme)
+ if "/" not in theme:
+ theme = f"{django_settings.STATIC_URL}djedi/themes/{theme}/theme.css"
- context['THEME'] = theme
- context['VERSION'] = djedi.__version__
+ context["THEME"] = theme
+ context["VERSION"] = djedi.__version__
return context
diff --git a/djedi/admin/urls.py b/djedi/admin/urls.py
index eac7dfd1..752475c9 100644
--- a/djedi/admin/urls.py
+++ b/djedi/admin/urls.py
@@ -2,15 +2,15 @@
from .api import LoadApi, NodeApi, NodeEditor, PublishApi, RenderApi, RevisionsApi
from .cms import DjediCMS
-app_name = 'djedi'
+app_name = "djedi"
urlpatterns = patterns(
- url(r'^$', DjediCMS.as_view(), name='cms'),
- url(r'^node/(?P.+)/editor$', NodeEditor.as_view(), name='cms.editor'),
- url(r'^node/(?P.+)/load$', LoadApi.as_view(), name='api.load'),
- url(r'^node/(?P.+)/publish$', PublishApi.as_view(), name='api.publish'),
- url(r'^node/(?P.+)/revisions$', RevisionsApi.as_view(), name='api.revisions'),
- url(r'^node/(?P.+)$', NodeApi.as_view(), name='api'),
- url(r'^plugin/(?P\w+)$', RenderApi.as_view(), name='api.render'),
- url(r'^api/', include('djedi.rest.urls', namespace='rest'))
+ url(r"^$", DjediCMS.as_view(), name="cms"),
+ url(r"^node/(?P.+)/editor$", NodeEditor.as_view(), name="cms.editor"),
+ url(r"^node/(?P.+)/load$", LoadApi.as_view(), name="api.load"),
+ url(r"^node/(?P.+)/publish$", PublishApi.as_view(), name="api.publish"),
+ url(r"^node/(?P.+)/revisions$", RevisionsApi.as_view(), name="api.revisions"),
+ url(r"^node/(?P.+)$", NodeApi.as_view(), name="api"),
+ url(r"^plugin/(?P\w+)$", RenderApi.as_view(), name="api.render"),
+ url(r"^api/", include("djedi.rest.urls", namespace="rest")),
)
diff --git a/djedi/auth/__init__.py b/djedi/auth/__init__.py
index 74576b2b..726dc97e 100644
--- a/djedi/auth/__init__.py
+++ b/djedi/auth/__init__.py
@@ -4,23 +4,25 @@
def has_permission(request):
- user = getattr(request, 'user', None)
+ user = getattr(request, "user", None)
if user:
if user.is_superuser:
return True
- if user.is_staff and user.groups.filter(name__iexact='djedi').exists():
+ if user.is_staff and user.groups.filter(name__iexact="djedi").exists():
return True
else:
- _log.warning("Request does not have `user` attribute. Make sure that "
- "Djedi middleware is used after AuthenticationMiddleware")
+ _log.warning(
+ "Request does not have `user` attribute. Make sure that "
+ "Djedi middleware is used after AuthenticationMiddleware"
+ )
return False
def get_username(request):
user = request.user
- if hasattr(user, 'get_username'):
+ if hasattr(user, "get_username"):
return user.get_username()
else:
return user.username
diff --git a/djedi/backends/django/cache/backend.py b/djedi/backends/django/cache/backend.py
index 22a7208b..eb68d5df 100644
--- a/djedi/backends/django/cache/backend.py
+++ b/djedi/backends/django/cache/backend.py
@@ -1,22 +1,20 @@
-import six
from django.core.cache import InvalidCacheBackendError
-from djedi.utils.encoding import smart_str, smart_unicode
-from cio.backends.base import CacheBackend
from django.core.cache.backends.locmem import LocMemCache
+from cio.backends.base import CacheBackend
from djedi.compat import get_cache
+from djedi.utils.encoding import smart_str, smart_unicode
class DjangoCacheBackend(CacheBackend):
-
def __init__(self, **config):
"""
Get cache backend. Look for djedi specific cache first, then fallback on default
"""
- super(DjangoCacheBackend, self).__init__(**config)
+ super().__init__(**config)
try:
- cache_name = self.config.get('NAME', 'djedi')
+ cache_name = self.config.get("NAME", "djedi")
cache = get_cache(cache_name)
except (InvalidCacheBackendError, ValueError):
from django.core.cache import cache
@@ -33,10 +31,14 @@ def _get_many(self, keys):
return self._cache.get_many(keys)
def _set(self, key, value):
- self._cache.set(key, value, timeout=None) # TODO: Fix eternal timeout like viewlet
+ self._cache.set(
+ key, value, timeout=None
+ ) # TODO: Fix eternal timeout like viewlet
def _set_many(self, data):
- self._cache.set_many(data, timeout=None) # TODO: Fix eternal timeout like viewlet
+ self._cache.set_many(
+ data, timeout=None
+ ) # TODO: Fix eternal timeout like viewlet
def _delete(self, key):
self._cache.delete(key)
@@ -50,31 +52,30 @@ def _encode_content(self, uri, content):
"""
if content is None:
content = self.NONE
- return smart_str('|'.join([six.text_type(uri), content]))
+ return smart_str("|".join([str(uri), content]))
def _decode_content(self, content):
"""
Split node string to uri and content and convert back to unicode.
"""
content = smart_unicode(content)
- uri, _, content = content.partition(u'|')
+ uri, _, content = content.partition("|")
if content == self.NONE:
content = None
return uri or None, content
class DebugLocMemCache(LocMemCache):
-
def __init__(self, *args, **kwargs):
self.calls = 0
self.hits = 0
self.misses = 0
self.sets = 0
- super(DebugLocMemCache, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def get(self, key, default=None, version=None, **kwargs):
- result = super(DebugLocMemCache, self).get(key, default=default, version=version)
- if kwargs.get('count', True):
+ result = super().get(key, default=default, version=version)
+ if kwargs.get("count", True):
self.calls += 1
if result is None:
self.misses += 1
@@ -91,16 +92,16 @@ def get_many(self, keys, version=None):
hits = len(d)
self.calls += 1
self.hits += hits
- self.misses += (len(keys) - hits)
+ self.misses += len(keys) - hits
return d
def set(self, *args, **kwargs):
- super(DebugLocMemCache, self).set(*args, **kwargs)
+ super().set(*args, **kwargs)
self.calls += 1
self.sets += 1
def set_many(self, data, *args, **kwargs):
- result = super(DebugLocMemCache, self).set_many(data, *args, **kwargs)
+ result = super().set_many(data, *args, **kwargs)
self.calls -= len(data) # Remove calls from set()
self.calls += 1
return result
diff --git a/djedi/backends/django/db/backend.py b/djedi/backends/django/db/backend.py
index 85c77f1b..52e3a837 100644
--- a/djedi/backends/django/db/backend.py
+++ b/djedi/backends/django/db/backend.py
@@ -1,6 +1,7 @@
import logging
from django.db import IntegrityError
+
from cio.backends.base import DatabaseBackend
from cio.backends.exceptions import NodeDoesNotExist, PersistenceError
@@ -12,15 +13,17 @@
class DjangoModelStorageBackend(DatabaseBackend):
- scheme = 'db'
+ scheme = "db"
def __init__(self, **config):
- super(DjangoModelStorageBackend, self).__init__(**config)
+ super().__init__(**config)
def get_many(self, uris):
- storage_keys = dict((self._build_key(uri), uri) for uri in uris)
+ storage_keys = {self._build_key(uri): uri for uri in uris}
stored_nodes = Node.objects.filter(key__in=storage_keys.keys())
- stored_nodes = stored_nodes.values_list('key', 'content', 'plugin', 'version', 'is_published', 'meta')
+ stored_nodes = stored_nodes.values_list(
+ "key", "content", "plugin", "version", "is_published", "meta"
+ )
# Filter matching nodes
nodes = {}
@@ -34,9 +37,9 @@ def get_many(self, uris):
if (uri.version == version) or (is_published and not uri.version):
meta = self._decode_meta(meta, is_published=is_published)
nodes[uri] = {
- 'uri': uri.clone(ext=plugin, version=version),
- 'content': content,
- 'meta': meta
+ "uri": uri.clone(ext=plugin, version=version),
+ "content": content,
+ "meta": meta,
}
return nodes
@@ -47,7 +50,9 @@ def publish(self, uri, **meta):
if not node.is_published:
# Assign version number
if not node.version.isdigit():
- revisions = Node.objects.filter(key=node.key).values_list('version', flat=True)
+ revisions = Node.objects.filter(key=node.key).values_list(
+ "version", flat=True
+ )
version = self._get_next_version(revisions)
node.version = version
@@ -63,9 +68,12 @@ def publish(self, uri, **meta):
def get_revisions(self, uri):
key = self._build_key(uri)
- nodes = Node.objects.filter(key=key).order_by('date_created')
- revisions = nodes.values_list('plugin', 'version', 'is_published')
- return [(key.clone(ext=plugin, version=version), is_published) for plugin, version, is_published in revisions]
+ nodes = Node.objects.filter(key=key).order_by("date_created")
+ revisions = nodes.values_list("plugin", "version", "is_published")
+ return [
+ (key.clone(ext=plugin, version=version), is_published)
+ for plugin, version, is_published in revisions
+ ]
def _get(self, uri):
key = self._build_key(uri)
@@ -92,10 +100,10 @@ def _create(self, uri, content, **meta):
plugin=uri.ext,
version=uri.version,
is_published=False,
- meta=meta
+ meta=meta,
)
except IntegrityError as e:
- raise PersistenceError('Failed to create node for uri "%s"; %s' % (uri, e))
+ raise PersistenceError(f'Failed to create node for uri "{uri}"; {e}')
def _update(self, uri, content, **meta):
node = self._get(uri)
@@ -115,9 +123,9 @@ def _delete(self, node):
def _serialize(self, uri, node):
meta = self._decode_meta(node.meta, is_published=node.is_published)
return {
- 'uri': uri.clone(ext=node.plugin, version=node.version),
- 'content': node.content,
- 'meta': meta
+ "uri": uri.clone(ext=node.plugin, version=node.version),
+ "content": node.content,
+ "meta": meta,
}
def _update_meta(self, node, meta):
diff --git a/djedi/backends/django/db/models.py b/djedi/backends/django/db/models.py
index 4541776a..63cfe7cb 100644
--- a/djedi/backends/django/db/models.py
+++ b/djedi/backends/django/db/models.py
@@ -12,5 +12,5 @@ class Node(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
- app_label = u'djedi'
- db_table = 'djedi_node'
+ app_label = "djedi"
+ db_table = "djedi_node"
diff --git a/djedi/compat.py b/djedi/compat.py
index 8f38c43e..aaf35da2 100644
--- a/djedi/compat.py
+++ b/djedi/compat.py
@@ -1,13 +1,12 @@
-import django
-
+from collections import namedtuple
from functools import partial
-from sys import version_info
+from inspect import getfullargspec
+import django
from django.shortcuts import render
from django.template.loader import render_to_string
from django.template.response import TemplateResponse as BaseTemplateResponse
-
if django.VERSION < (1, 6):
from django.conf.urls.defaults import include, url
else:
@@ -15,18 +14,20 @@
if django.VERSION < (2, 0):
- from django.core.urlresolvers import reverse, NoReverseMatch
+ from django.core.urlresolvers import NoReverseMatch, reverse
else:
- from django.urls import reverse, NoReverseMatch
+ from django.urls import NoReverseMatch, reverse
def patterns(*urls):
if django.VERSION < (1, 6):
from django.conf.urls.defaults import patterns
- return patterns('', *urls)
+
+ return patterns("", *urls)
elif django.VERSION < (1, 10):
from django.conf.urls import patterns
- return patterns('', *urls)
+
+ return patterns("", *urls)
return list(urls)
@@ -34,16 +35,28 @@ def patterns(*urls):
if django.VERSION < (2, 0):
from django.template.library import parse_bits
else:
- def parse_bits(parser, bits, params, varargs, varkw, defaults,
- takes_context, name):
+
+ def parse_bits(
+ parser, bits, params, varargs, varkw, defaults, takes_context, name
+ ):
from django.template import library
- return library.parse_bits(
- parser=parser, bits=bits, params=params, varargs=varargs,
- varkw=varkw, defaults=defaults, kwonly=(), kwonly_defaults=(),
- takes_context=takes_context, name=name)
- def generic_tag_compiler(parser, token, params, varargs, varkw, defaults,
- name, takes_context, node_class):
+ return library.parse_bits(
+ parser=parser,
+ bits=bits,
+ params=params,
+ varargs=varargs,
+ varkw=varkw,
+ defaults=defaults,
+ kwonly=(),
+ kwonly_defaults=(),
+ takes_context=takes_context,
+ name=name,
+ )
+
+ def generic_tag_compiler(
+ parser, token, params, varargs, varkw, defaults, name, takes_context, node_class
+ ):
"""
Returns a template.Node subclass.
@@ -52,23 +65,26 @@ def generic_tag_compiler(parser, token, params, varargs, varkw, defaults,
https://github.com/django/django/blob/stable/1.8.x/django/template/base.py#L1089
"""
bits = token.split_contents()[1:]
- args, kwargs = parse_bits(parser, bits, params, varargs, varkw,
- defaults, takes_context, name)
+ args, kwargs = parse_bits(
+ parser, bits, params, varargs, varkw, defaults, takes_context, name
+ )
return node_class(takes_context, args, kwargs)
+
else:
- from django.template.base import parse_bits
from django.template.base import generic_tag_compiler # noqa
+ from django.template.base import parse_bits
if django.VERSION >= (1, 8):
# Always use the Django template engine on Django 1.8.
- render_to_string = partial(render_to_string, using='django')
- render = partial(render, using='django')
+ render_to_string = partial(render_to_string, using="django")
+ render = partial(render, using="django")
class TemplateResponse(BaseTemplateResponse):
def __init__(self, *args, **kwargs):
- kwargs['using'] = 'django'
- super(TemplateResponse, self).__init__(*args, **kwargs)
+ kwargs["using"] = "django"
+ super().__init__(*args, **kwargs)
+
else:
TemplateResponse = BaseTemplateResponse
@@ -82,30 +98,28 @@ def get_cache(name):
return caches[name]
-if version_info < (3,):
- from inspect import getargspec
-else:
- from collections import namedtuple
- from inspect import getfullargspec
-
- ArgSpec = namedtuple('ArgSpec', ['args', 'varargs', 'keywords', 'defaults'])
-
- def getargspec(func):
- spec = getfullargspec(func)
- return ArgSpec(
- args=spec.args,
- varargs=spec.varargs,
- keywords=spec.varkw,
- defaults=spec.defaults,
- )
+ArgSpec = namedtuple("ArgSpec", ["args", "varargs", "keywords", "defaults"])
+
+
+def getargspec(func):
+ spec = getfullargspec(func)
+ return ArgSpec(
+ args=spec.args,
+ varargs=spec.varargs,
+ keywords=spec.varkw,
+ defaults=spec.defaults,
+ )
+
-__all__ = ['render_to_string',
- 'render',
- 'patterns',
- 'include',
- 'url',
- 'reverse',
- 'NoReverseMatch',
- 'generic_tag_compiler',
- 'parse_bits',
- 'get_cache']
+__all__ = [
+ "render_to_string",
+ "render",
+ "patterns",
+ "include",
+ "url",
+ "reverse",
+ "NoReverseMatch",
+ "generic_tag_compiler",
+ "parse_bits",
+ "get_cache",
+]
diff --git a/djedi/middleware/__init__.py b/djedi/middleware/__init__.py
index 8b6d5e28..43ad010e 100644
--- a/djedi/middleware/__init__.py
+++ b/djedi/middleware/__init__.py
@@ -2,8 +2,7 @@
from cio.pipeline import pipeline
-class DjediMiddleware(object):
-
+class DjediMiddleware:
def __init__(self, get_response=None):
self.get_response = get_response
@@ -12,8 +11,7 @@ def __call__(self, request):
if not response:
try:
response = self.get_response(request)
- response = self.process_response(request=request,
- response=response)
+ response = self.process_response(request=request, response=response)
except Exception as e:
self.process_exception(request=request, exception=e)
raise
diff --git a/djedi/middleware/admin.py b/djedi/middleware/admin.py
index fbcfa488..f74e2363 100644
--- a/djedi/middleware/admin.py
+++ b/djedi/middleware/admin.py
@@ -3,7 +3,6 @@
class DjediAdminMiddleware(DjediMiddleware, AdminPanelMixin):
-
def process_response(self, request, response):
self.inject_admin_panel(request, response)
- return super(DjediAdminMiddleware, self).process_response(request, response)
+ return super().process_response(request, response)
diff --git a/djedi/middleware/mixins.py b/djedi/middleware/mixins.py
index 6dfb3738..f2d1481b 100644
--- a/djedi/middleware/mixins.py
+++ b/djedi/middleware/mixins.py
@@ -1,71 +1,70 @@
import logging
-import cio
-
from django.core.exceptions import ImproperlyConfigured
from django.utils import translation
+import cio
from cio.conf import settings
from cio.pipeline import pipeline
from djedi.auth import has_permission
-from djedi.compat import reverse, NoReverseMatch
+from djedi.compat import NoReverseMatch, reverse
from djedi.utils.templates import render_embed
_log = logging.getLogger(__name__)
-class TranslationMixin(object):
-
+class TranslationMixin:
def activate_language(self):
# Activate current django translation
language = translation.get_language()
cio.env.push_state(i18n=language)
-class AdminPanelMixin(object):
-
+class AdminPanelMixin:
def inject_admin_panel(self, request, response):
# Do not inject admin panel on gzipped responses
- if 'gzip' in response.get('Content-Encoding', ''):
- _log.debug('gzip detected, not injecting panel.')
+ if "gzip" in response.get("Content-Encoding", ""):
+ _log.debug("gzip detected, not injecting panel.")
return
# Only inject admin panel in html pages
- content_type = response.get('Content-Type', '').split(';')[0]
- if content_type not in ('text/html', 'application/xhtml+xml'):
- _log.debug('Non-HTML Content-Type detected, not injecting')
+ content_type = response.get("Content-Type", "").split(";")[0]
+ if content_type not in ("text/html", "application/xhtml+xml"):
+ _log.debug("Non-HTML Content-Type detected, not injecting")
return
# Do not inject admin panel in admin
try:
- admin_prefix = reverse('admin:index')
+ admin_prefix = reverse("admin:index")
except NoReverseMatch:
_log.debug(
'No reverse match for "admin:index", can\'t detect '
- 'django-admin pages'
+ "django-admin pages"
)
else:
if request.path.startswith(admin_prefix):
_log.debug(
- 'admin page detected, not injecting panel. admin_prefix=%r',
- admin_prefix
+ "admin page detected, not injecting panel. admin_prefix=%r",
+ admin_prefix,
)
return
try:
- djedi_cms_url = reverse('admin:djedi:cms')
+ djedi_cms_url = reverse("admin:djedi:cms")
except NoReverseMatch:
- raise ImproperlyConfigured('Could not find djedi in your url conf, '
- 'enable django admin or include '
- 'djedi.urls within the admin namespace.')
+ raise ImproperlyConfigured(
+ "Could not find djedi in your url conf, "
+ "enable django admin or include "
+ "djedi.urls within the admin namespace."
+ )
else:
if request.path.startswith(djedi_cms_url):
- _log.debug('djedi page detected, not injecting panel')
+ _log.debug("djedi page detected, not injecting panel")
return
# Validate user permissions
if not has_permission(request):
- _log.debug('insufficient permissions, not injecting.')
+ _log.debug("insufficient permissions, not injecting.")
return
embed = self.render_cms()
@@ -82,20 +81,20 @@ def get_requested_uri(node):
)
return uri
- defaults = dict(
- (get_requested_uri(node), node.initial)
- for node in pipeline.history.list('get')
- )
+ defaults = {
+ get_requested_uri(node): node.initial
+ for node in pipeline.history.list("get")
+ }
return render_embed(nodes=defaults)
def body_append(self, response, html):
- idx = response.content.lower().rfind(b'