Skip to content

Commit

Permalink
Merge pull request #146 from PetrDlouhy/Django20
Browse files Browse the repository at this point in the history
Compatibility fixes for Django 2.0 and 2.1
  • Loading branch information
vkurup authored Oct 26, 2019
2 parents 06fcd79 + e087167 commit 21218e8
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 46 deletions.
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

0 comments on commit 21218e8

Please sign in to comment.