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

Python 3 support and Django 1.8 support #19

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 20 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
language: python

python:
- "2.6"
- "2.7"
sudo: false
env:
- DJANGO=Django==1.4.10
- DJANGO=Django==1.5.5
- DJANGO=Django==1.6
- TOXENV=py26_django14
- TOXENV=py27_django14
- TOXENV=py26_django15
- TOXENV=py27_django15
- TOXENV=py26_django16
- TOXENV=py27_django16
- TOXENV=py33_django16
- TOXENV=py34_django16
- TOXENV=py27_django17
- TOXENV=py33_django17
- TOXENV=py34_django17
- TOXENV=py27_django18
- TOXENV=py33_django18
- TOXENV=py34_django18
- TOXENV=flake8
- TOXENV=coverage


install:
- pip install $DJANGO flake8 python-coveralls
- pip install -e .
- pip install "file://`pwd`#egg=djedi-cms[tests]"
- pip install tox

script:
- make flake8
- coverage run --source djedi runtests.py
- coverage report
- tox

after_success:
- coveralls
2 changes: 1 addition & 1 deletion djedi/admin/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from collections import defaultdict
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, Http404, HttpResponseBadRequest
from django.template.response import TemplateResponse
from django.utils.http import urlunquote
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt
Expand All @@ -14,6 +13,7 @@

from .exceptions import InvalidNodeData
from .mixins import JSONResponseMixin, DjediContextMixin
from ..compat import TemplateResponse
from .. import auth


Expand Down
3 changes: 2 additions & 1 deletion djedi/admin/cms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

from django.contrib.admin import ModelAdmin
from django.core.exceptions import PermissionDenied
from django.shortcuts import render
from django.views.generic import View

from .mixins import DjediContextMixin
from ..auth import has_permission
from ..compat import render


class Admin(ModelAdmin):
Expand Down
10 changes: 5 additions & 5 deletions djedi/backends/django/cache/backend.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import six
from django.core.cache import InvalidCacheBackendError
from django.utils.encoding import smart_str, smart_unicode
from djedi.utils.encoding import smart_str, smart_unicode
from cio.backends.base import CacheBackend


Expand Down Expand Up @@ -47,15 +48,14 @@ def _encode_content(self, uri, content):
"""
if content is None:
content = self.NONE
return smart_str(unicode(uri) + u'|' + content)
return smart_str('|'.join([six.text_type(uri), content]))

def _decode_content(self, content):
"""
Split node string to uri and content and convert back to unicode.
"""
uri, _, content = content.partition('|')
content = smart_unicode(content)
uri, _, content = content.partition(u'|')
if content == self.NONE:
content = None
else:
content = smart_unicode(content)
return uri or None, content
5 changes: 4 additions & 1 deletion djedi/backends/django/db/backend.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import logging

from django.db import IntegrityError
from cio.backends.base import DatabaseBackend
from cio.backends.exceptions import NodeDoesNotExist, PersistenceError
from .models import Node

# Use absolute import here or Django 1.7 complains about duplicate models.
from djedi.backends.django.db.models import Node

logger = logging.getLogger(__name__)

Expand Down
21 changes: 21 additions & 0 deletions djedi/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import django

from functools import partial

from django.shortcuts import render
from django.template.loader import render_to_string
from django.template.response import TemplateResponse as BaseTemplateResponse

__all__ = ['render_to_string', 'render']

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')

class TemplateResponse(BaseTemplateResponse):
def __init__(self, *args, **kwargs):
kwargs['using'] = 'django'
super(TemplateResponse, self).__init__(*args, **kwargs)
else:
TemplateResponse = BaseTemplateResponse
18 changes: 11 additions & 7 deletions djedi/middleware/mixins.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import cio
import json

import cio

from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse, NoReverseMatch
from django.template.loader import render_to_string
from django.utils import translation
from django.utils.encoding import smart_unicode

from cio.pipeline import pipeline
from djedi.auth import has_permission
from djedi.compat import render_to_string
from djedi.utils.encoding import smart_unicode


class TranslationMixin(object):
Expand Down Expand Up @@ -56,11 +59,12 @@ def render_cms(self):

def body_append(self, response, html):
content = smart_unicode(response.content)
end_body = u'</body>'
end_body_index = content.lower().rfind(end_body)
idx = content.lower().rfind(u'</body>')

if end_body_index >= 0:
response.content = content[:end_body_index] + html + end_body + content[end_body_index + 7:]
if idx >= 0:
response.content = u''.join((content[:idx],
html,
content[idx:]))

if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
14 changes: 7 additions & 7 deletions djedi/plugins/img.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import json
import six
from django.utils.html import escape

try:
import cStringIO as StringIO
except ImportError:
import StringIO
from cio.plugins.base import BasePlugin
from django.core.files.uploadedfile import InMemoryUploadedFile
from hashlib import sha1
Expand All @@ -27,7 +23,11 @@ def _url(self, filename):
def _create_filename(self, filename, **kwargs):
name, ext = path.splitext(filename)
dir, name = name.rsplit(path.sep, 1)
name += ''.join((key + str(value) for key, value in kwargs.iteritems()))
name += ''.join(sorted(key + str(value) for key, value in six.iteritems(kwargs)))

if six.PY3:
name = name.encode('utf-8')

name = sha1(name).hexdigest()
subdir = name[:2]
return path.sep.join((dir, subdir, name + ext))
Expand Down Expand Up @@ -94,7 +94,7 @@ def save(self, data):

# Write file
if filename != data.get('filename'):
new_file = StringIO.StringIO()
new_file = six.BytesIO()
image.save(new_file, format)
filename = self._save(filename, new_file)

Expand Down
14 changes: 7 additions & 7 deletions djedi/templates/djedi/cms/cms.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load static %}
{% load static staticfiles %}
<!DOCTYPE html>
<html>
<head>
Expand All @@ -10,8 +10,8 @@

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="{{ STATIC_URL }}djedi/vendor/html5/html5shiv.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/vendor/html5/respond.min.js?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/html5/html5shiv.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/html5/respond.min.js' %}?v={{ VERSION }}"></script>
<![endif]-->
</head>
<body>
Expand Down Expand Up @@ -39,9 +39,9 @@
<section id="editor-panel" class="tab-pane active"></section>
<section id="settings-panel" class="tab-pane hide"></section>
</div>
<script src="{{ STATIC_URL }}djedi/vendor/jquery/jquery.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/vendor/bootstrap/js/bootstrap.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/cms/js/uri.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/cms/js/cms.js?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/jquery/jquery.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/bootstrap/js/bootstrap.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/cms/js/uri.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/cms/js/cms.js' %}?v={{ VERSION }}"></script>
</body>
</html>
16 changes: 8 additions & 8 deletions djedi/templates/djedi/plugins/base/editor.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load static %}
{% load static staticfiles %}
{% load url from future %}
<!DOCTYPE html>
<html>
Expand All @@ -14,8 +14,8 @@

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="{{ STATIC_URL }}djedi/vendor/html5/html5shiv.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/vendor/html5/respond.min.js?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/html5/html5shiv.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/html5/respond.min.js' %}?v={{ VERSION }}"></script>
<![endif]-->
</head>
<body class="editor">
Expand Down Expand Up @@ -55,11 +55,11 @@
<script>
window.DJEDI_ENDPOINT = '{% url 'admin:djedi:cms' %}';
</script>
<script src="{{ STATIC_URL }}djedi/vendor/jquery/jquery.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/vendor/jquery.form/jquery.form.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/vendor/bootstrap/js/bootstrap.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/cms/js/uri.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/plugins/base/js/editor.js?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/jquery/jquery.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/jquery.form/jquery.form.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/vendor/bootstrap/js/bootstrap.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/cms/js/uri.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/plugins/base/js/editor.js' %}?v={{ VERSION }}"></script>
{% block plugin_script %}{% endblock plugin_script %}
{% endblock script %}
</body>
Expand Down
14 changes: 7 additions & 7 deletions djedi/templates/djedi/plugins/img/editor.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{% extends 'djedi/plugins/base/editor.html' %}
{% load static %}
{% load static staticfiles %}

{% block plugin_style %}
<link href="{{ STATIC_URL }}djedi/plugins/img/css/jquery.Jcrop.min.css?v={{ VERSION }}" rel="stylesheet" media="screen">
<link href="{{ STATIC_URL }}djedi/plugins/img/css/img.css?v={{ VERSION }}" rel="stylesheet" media="screen">
<link href="{% static 'djedi/plugins/img/css/jquery.Jcrop.min.css' %}?v={{ VERSION }}" rel="stylesheet" media="screen">
<link href="{% static 'djedi/plugins/img/css/img.css' %}?v={{ VERSION }}" rel="stylesheet" media="screen">
{% endblock %}

{% block tabs %}
Expand Down Expand Up @@ -71,10 +71,10 @@
{% endblock editor %}

{% block plugin_script %}
<script src="{{ STATIC_URL }}djedi/plugins/img/js/jquery.ui.widget.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/plugins/img/js/jquery.fileupload.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/plugins/img/js/jquery.Jcrop.min.js?v={{ VERSION }}"></script>
<script src="{{ STATIC_URL }}djedi/plugins/img/js/img.js?v={{ VERSION }}"></script>
<script src="{% static 'djedi/plugins/img/js/jquery.ui.widget.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/plugins/img/js/jquery.fileupload.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/plugins/img/js/jquery.Jcrop.min.js' %}?v={{ VERSION }}"></script>
<script src="{% static 'djedi/plugins/img/js/img.js' %}?v={{ VERSION }}"></script>
<script>
image = new window.ImageEditor({
uri: '{{ uri }}',
Expand Down
7 changes: 5 additions & 2 deletions djedi/templatetags/djedi_admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import json
import logging

from django import template
from django.template.loader import render_to_string

from cio.pipeline import pipeline
from ..auth import has_permission
from djedi.auth import has_permission
from djedi.compat import render_to_string


register = template.Library()
logger = logging.getLogger(__name__)
Expand Down
3 changes: 2 additions & 1 deletion djedi/templatetags/djedi_tags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import cio
import six
import textwrap
from django import template
from django.template import TemplateSyntaxError
Expand Down Expand Up @@ -69,7 +70,7 @@ def __init__(self, tokens, node, kwargs):

def render(self, context):
# Resolve tag kwargs against context
resolved_kwargs = dict((key, value.resolve(context)) for key, value in self.kwargs.iteritems())
resolved_kwargs = dict((key, value.resolve(context)) for key, value in six.iteritems(self.kwargs))
edit = resolved_kwargs.pop('edit', True)

return render_node(self.node, context=resolved_kwargs, edit=edit)
Expand Down
5 changes: 3 additions & 2 deletions djedi/templatetags/template.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from functools import partial
from inspect import getargspec
from django import template
from django.template import Node, TemplateSyntaxError, generic_tag_compiler
from django.template import Context
from django.template.base import Node, TemplateSyntaxError, generic_tag_compiler

register = template.Library()

Expand Down Expand Up @@ -34,7 +35,7 @@ def __init__(self, takes_context, args, kwargs):
self.args = args
self.kwargs = kwargs

resolved_args, resolved_kwargs = self.get_resolved_arguments({})
resolved_args, resolved_kwargs = self.get_resolved_arguments(Context({}))

self.resolved_args = resolved_args
self.resolved_kwargs = resolved_kwargs
Expand Down
18 changes: 14 additions & 4 deletions djedi/tests/base.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import cio
import shutil

import cio
import django

from contextlib import contextmanager

from django.conf import settings
from django.contrib.auth.models import User, Group
from django.test import Client
from django.test import TransactionTestCase


if django.VERSION < (1, 8):
DEBUG_CURSOR_ATTR = 'use_debug_cursor'
else:
DEBUG_CURSOR_ATTR = 'force_debug_cursor'


class DjediTest(TransactionTestCase):

def setUp(self):
Expand Down Expand Up @@ -52,15 +62,15 @@ def assertCache(self, calls=-1, hits=-1, misses=-1):
def assertDB(self, calls=-1, selects=-1, inserts=-1, updates=-1):
from django.db import connection

pre_debug_cursor = connection.use_debug_cursor
connection.use_debug_cursor = True
pre_debug_cursor = getattr(connection, DEBUG_CURSOR_ATTR)
setattr(connection, DEBUG_CURSOR_ATTR, True)
pre_num_queries = len(connection.queries)

yield

queries = connection.queries[pre_num_queries:]
num_queries = len(queries)
connection.use_debug_cursor = pre_debug_cursor
setattr(connection, DEBUG_CURSOR_ATTR, pre_debug_cursor)

if calls >= 0:
assert num_queries == calls
Expand Down
1 change: 1 addition & 0 deletions djedi/tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
)

INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
Expand Down