Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility fixes for Django 2.0 and 2.1 #146

Merged
merged 9 commits into from
Oct 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,26 @@ python:
- "3.6"

env:
- TOXENV=py27-1.8.X,py34-1.8.X,py35-1.8.X
- TOXENV=py27-1.10.X,py34-1.10.X,py35-1.10.X
- TOXENV=py27-1.11.X,py34-1.11.X,py36-1.11.X
- TOXENV=py27-1.8.X
- TOXENV=py34-1.8.X
- TOXENV=py35-1.8.X

- TOXENV=py27-1.10.X
- TOXENV=py34-1.10.X
- TOXENV=py35-1.10.X

- TOXENV=py27-1.11.X
- TOXENV=py34-1.11.X
- TOXENV=py35-1.11.X
- TOXENV=py36-1.11.X

- TOXENV=py34-2.0.X
- TOXENV=py35-2.0.X
- TOXENV=py36-2.0.X

- TOXENV=py35-2.1.X
- TOXENV=py36-2.1.X

- TOXENV=coverage
- TOXENV=docs
- TOXENV=qunit
Expand All @@ -41,9 +58,6 @@ install:
script:
- tox

branches:
only:
- master

after_success:
- coveralls
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Features
Installation
--------------------------------------

django-scribbler requires Django 1.8, 1.10, or 1.11, and Python 2.7 or >= 3.4.
django-scribbler requires Django 1.8, 1.10, 1.11, or 2.0, and Python 2.7 or >= 3.4.

To install from PyPi::

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
},
"dependencies": {
"backbone": ">=1.2 <1.3",
"codemirror": ">=5.10 <6.0",
"codemirror": "^5.40.0",
"jquery": ">=2.2 <2.3",
"jshint": "^2.9.5",
"jshint": "^2.9.6",
"less": "^2.7.3",
"phantomjs-prebuilt": "^2.1.16",
"underscore": ">=1.8 <1.9"
Expand Down
38 changes: 27 additions & 11 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
#!/usr/bin/env python
import sys
import os
from optparse import OptionParser

import django
from django import VERSION as django_version
from django.conf import settings

MIDDLEWARES=(
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)

class DisableMigrations(object):
def __contains__(self, item):
return True

def __getitem__(self, item):
return 'notmigrations'


if not settings.configured:
settings.configure(
Expand All @@ -22,13 +38,8 @@
'django.contrib.staticfiles',
'scribbler',
),
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
),
MIDDLEWARE_CLASSES=MIDDLEWARES,
MIDDLEWARE=MIDDLEWARES,
SITE_ID=1,
SECRET_KEY='super-secret',

Expand Down Expand Up @@ -68,7 +79,7 @@
# https://docs.djangoproject.com/en/1.11/ref/settings/#migration-modules
'scribbler': 'scribbler.tests.migrations' if django_version < (1, 9) else None,
'dayslog': 'dayslog.tests.migrations' if django_version < (1, 9) else None,
},
} if django_version >= (1, 9) else DisableMigrations(),
MEDIA_ROOT='',
MEDIA_URL='/media/',
STATIC_ROOT='',
Expand All @@ -80,18 +91,23 @@
from django.test.utils import get_runner


def runtests():
def runtests(*test_args, **kwargs):
if django_version < (1, 11):
# Try lots of ports until we find one we can use
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8099-9999'

if hasattr(django, 'setup'):
django.setup()
if not test_args:
test_args = ['scribbler', ]
TestRunner = get_runner(settings)
test_runner = TestRunner(verbosity=1, interactive=True, failfast=False)
failures = test_runner.run_tests(['scribbler', ])
failures = test_runner.run_tests(test_args)
sys.exit(failures)


if __name__ == '__main__':
runtests()
parser = OptionParser()

(options, args) = parser.parse_args()
runtests(*args)
2 changes: 1 addition & 1 deletion scribbler/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

def default_cache_key(slug, url):
"Construct a cache key for a given slug/url pair."
sha = hashlib.sha1('{0}#{1}'.format(url, slug).encode('ascii'))
sha = hashlib.sha1('{0}#{1}'.format(url, slug).encode('utf8'))
return '{0}:{1}'.format(CACHE_PREFIX, sha.hexdigest())


Expand Down
15 changes: 11 additions & 4 deletions scribbler/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@

from django import forms
from django.db.models import ObjectDoesNotExist, FieldDoesNotExist
from django.template import StringOrigin
from django.core.urlresolvers import reverse
try:
from django.template import Origin
except ImportError: # Django<2.0
from django.template import StringOrigin as Origin
try:
from django.urls import reverse
except ImportError: # Django<2.0
from django.core.urlresolvers import reverse
from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import force_text

from .models import Scribble

Expand All @@ -17,7 +24,7 @@ class ScribbleFormMixin(object):
def clean_content(self):
content = self.cleaned_data.get('content', '')
if content:
origin = StringOrigin(content)
origin = Origin(content)

try:
from django.template.debug import DebugLexer, DebugParser
Expand All @@ -27,7 +34,7 @@ def clean_content(self):
from django.template import Template
# Try to create a Template
try:
template = Template(template_string=origin)
template = Template(template_string=force_text(content), origin=origin)
# This is an error with creating the template
except Exception as e:
self.exc_info = {
Expand Down
12 changes: 7 additions & 5 deletions scribbler/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
from django.db import models
from django.db.models.signals import post_save, post_delete, pre_save
from django.dispatch import receiver
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
try:
from django.utils.six import PY3
except ImportError:
Expand Down Expand Up @@ -35,16 +39,14 @@ def __str__(self):
class Meta(object):
unique_together = ('slug', 'url')

@models.permalink
def get_save_url(self):
if self.pk:
return ('edit-scribble', (), {'scribble_id': self.pk})
return reverse('edit-scribble', kwargs={'scribble_id': self.pk})
else:
return ('create-scribble', (), {})
return reverse('create-scribble')

@models.permalink
def get_delete_url(self):
return ('delete-scribble', (), {'scribble_id': self.pk})
return reverse('delete-scribble', kwargs={'scribble_id': self.pk})


@receiver(post_save, sender=Scribble)
Expand Down
17 changes: 14 additions & 3 deletions scribbler/templatetags/scribbler_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
from scribbler.views import build_scribble_context


try:
TOKEN_VAR = template_base.TokenType.VAR
TOKEN_BLOCK = template_base.TokenType.BLOCK
TOKEN_COMMENT = template_base.TokenType.COMMENT
except AttributeError:
TOKEN_VAR = template_base.TOKEN_VAR
TOKEN_BLOCK = template_base.TOKEN_BLOCK
TOKEN_COMMENT = template_base.TOKEN_COMMENT


register = template.Library()


Expand Down Expand Up @@ -88,24 +98,25 @@ def render(self, context):
return wrapper_template.render(context_data, request)



def rebuild_template_string(tokens):
"Reconstruct the original template from a list of tokens."
result = ''
for token in tokens:
value = token.contents
if token.token_type == template_base.TOKEN_VAR:
if token.token_type == TOKEN_VAR:
value = '{0} {1} {2}'.format(
template_base.VARIABLE_TAG_START,
value,
template_base.VARIABLE_TAG_END,
)
elif token.token_type == template_base.TOKEN_BLOCK:
elif token.token_type == TOKEN_BLOCK:
value = '{0} {1} {2}'.format(
template_base.BLOCK_TAG_START,
value,
template_base.BLOCK_TAG_END,
)
elif token.token_type == template_base.TOKEN_COMMENT:
elif token.token_type == TOKEN_COMMENT:
value = '{0} {1} {2}'.format(
template_base.COMMENT_TAG_START,
value,
Expand Down
4 changes: 2 additions & 2 deletions scribbler/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import string

from django.contrib.auth.models import User
from django.test import TestCase
from django.test import TransactionTestCase

from scribbler.models import Scribble


class ScribblerDataTestCase(TestCase):
class ScribblerDataTestCase(TransactionTestCase):
"Base test case for creating scribbler models."

def get_random_string(self, length=10):
Expand Down
5 changes: 4 additions & 1 deletion scribbler/tests/jinja2.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from __future__ import absolute_import # Python 2 only

from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.urlresolvers import reverse
try:
from django.urls import reverse
except ImportError: # Django<2.0
from django.core.urlresolvers import reverse

from jinja2 import Environment

Expand Down
Empty file.
22 changes: 22 additions & 0 deletions scribbler/tests/test_templatetags.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

"Test for template tags."
from __future__ import unicode_literals

Expand All @@ -12,6 +14,16 @@
from .base import ScribblerDataTestCase
from scribbler.conf import CACHE_TIMEOUT

class UnicodeURLTestCase(ScribblerDataTestCase):
"Test, that unicode characters in url got cached"

def testUnicodeURL(self):
scribble = self.create_scribble(
url='/foo/čřžžýü', slug='sidebar',
content='<p>Scribble content.</p>'
)
self.assertEquals(scribble.url, "/foo/čřžžýü")


class RenderScribbleTestCase(ScribblerDataTestCase):
"Tag to render a scribble for the current page."
Expand Down Expand Up @@ -70,6 +82,16 @@ def test_default_rendering(self):
result = self.render_template_tag(slug='"sidebar"')
self.assertTrue('<p>Default.</p>' in result)

def test_unicode_rendering(self):
"Render with unicode defaults when no scribbles exist."
# On Django>=1.9 ScribbleFormMixin.clean_content directly uses django.template.Template
# and also uses force_text that may fail for non-string objects that have __str__ with
# unicode output.
self.scribble.delete()
unicode_default = '<p>\u0422\u0435\u043a\u0441\u0442.</p>'
result = self.render_template_tag(slug='"sidebar"', default=unicode_default)
self.assertTrue(unicode_default in result)

def test_no_slug_given(self):
"Slug is required by the tag."
self.assertRaises(TemplateSyntaxError, self.render_template_tag, slug='')
Expand Down
6 changes: 5 additions & 1 deletion scribbler/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@

from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
try:
from django.urls import reverse
except ImportError: # Django<2.0
from django.core.urlresolvers import reverse
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import override_settings

Expand Down Expand Up @@ -469,4 +472,5 @@ def test_editor(self):
action = ActionChains(self.browser)
action.send_keys(Keys.F11)
action.perform()
self.browser.implicitly_wait(10)
self.assertTrue(self.browser.find_element_by_class_name("CodeMirror-fullscreen"))
18 changes: 14 additions & 4 deletions scribbler/tests/urls.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
from django.conf.urls import include, url, handler404, handler500
from django.http import HttpResponseNotFound, HttpResponseServerError
from django.contrib.auth import views as auth_views
from django.views.i18n import javascript_catalog
try:
from django.views.i18n import JavaScriptCatalog
javascript_catalog = JavaScriptCatalog.as_view()
except ImportError: # Django<1.10
from django.views.i18n import javascript_catalog


handler404 = 'scribbler.tests.urls.test_404'
handler500 = 'scribbler.tests.urls.test_500'


def test_404(request):
def test_404(request, exception=None):
return HttpResponseNotFound()


def test_500(request):
def test_500(request, exception=None):
return HttpResponseServerError()


js_info_dict = {
'packages': ('scribbler', ),
}

try:
login_url = url(r'^test/', auth_views.LoginView.as_view(template_name='test.html'))
except AttributeError:
login_url = url(r'^test/', auth_views.login, {'template_name': 'test.html'})

urlpatterns = [
url(r'^scribble/', include('scribbler.urls')),
url(r'^jsi18n/$', javascript_catalog, js_info_dict, name='jsi18n'),
url(r'^test/', auth_views.login, {'template_name': 'test.html'}),
login_url,
]
Loading