diff --git a/petale/api_views.py b/petale/api_views.py
index 745b96b..6dc1edb 100644
--- a/petale/api_views.py
+++ b/petale/api_views.py
@@ -14,11 +14,18 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import urlparse
+from __future__ import unicode_literals
+
import logging
+try:
+ from functools import reduce
+except ImportError:
+ pass
import requests
+from django.utils.six.moves.urllib import parse as urlparse
+
from django.db.models.query import Q, F
from django.http import StreamingHttpResponse, HttpResponse
from django.conf import settings
@@ -130,8 +137,8 @@ class PetalAPIView(APIView):
http_method_names = ['get', 'head', 'put', 'delete']
def get_petal(self, partner_name, cut_uuid, petal_name, if_match=None, if_none_match=None):
- if_match = if_match and map(str.strip, if_match.split(','))
- if_none_match = if_none_match and map(str.strip, if_none_match.split(','))
+ if_match = if_match and [x.strip() for x in if_match.split(',')]
+ if_none_match = if_none_match and [x.strip() for x in if_none_match.split(',')]
try:
qs = Petal.objects.filter(
@@ -175,7 +182,7 @@ class PetalAPIView(APIView):
def get(self, request, partner_name, cut_uuid, petal_name):
logger = logging.getLogger(__name__)
if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
- if_none_match = if_none_match and map(str.strip, if_none_match.split(','))
+ if_none_match = if_none_match and [x.strip() for x in if_none_match.split(',')]
petal = self.get_petal(partner_name, cut_uuid, petal_name)
if if_none_match:
diff --git a/petale/authentication.py b/petale/authentication.py
index edc0011..ab7d42f 100644
--- a/petale/authentication.py
+++ b/petale/authentication.py
@@ -14,11 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import urlparse
import logging
import requests
+from django.utils.six.moves.urllib import parse as urlparse
+
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
diff --git a/petale/models.py b/petale/models.py
index bf836fb..2941f51 100644
--- a/petale/models.py
+++ b/petale/models.py
@@ -14,8 +14,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+from __future__ import unicode_literals
+
import hashlib
+from django.utils import six
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
@@ -30,6 +33,7 @@ from . import utils
id_validator = RegexValidator('^[A-Za-z0-9-_]+$')
+@six.python_2_unicode_compatible
class Partner(models.Model):
name = models.CharField(
verbose_name=_('Partner'),
@@ -58,7 +62,7 @@ class Partner(models.Model):
default=0,
help_text=_('as bytes'))
- def __unicode__(self):
+ def __str__(self):
return self.name
def check_limits(self, size_delta, **kwargs):
@@ -80,7 +84,7 @@ class Partner(models.Model):
def notify_admins(self, subject, body, **kwargs):
if kwargs:
body += '\n'
- for key, value in kwargs.iteritems():
+ for key, value in kwargs.items():
body += '\n %s = %r' % (key, value)
send_mail(subject, body, None, self.admin_emails.split(','))
@@ -90,13 +94,14 @@ class Partner(models.Model):
ordering = ['name']
+@six.python_2_unicode_compatible
class CUT(models.Model):
uuid = models.CharField(
max_length=255,
validators=[id_validator],
unique=True)
- def __unicode__(self):
+ def __str__(self):
return self.uuid
class Meta:
@@ -113,11 +118,12 @@ def petal_directory(instance, filename):
return 'data/{0}/{1}/{2}/{3}'.format(
instance.partner.name,
- hashlib.md5(instance.cut.uuid).hexdigest()[:3],
+ hashlib.md5(instance.cut.uuid.encode('ascii')).hexdigest()[:3],
instance.cut.uuid,
instance.name)
+@six.python_2_unicode_compatible
class Petal(models.Model):
created_at = models.DateTimeField(
_('Created'),
@@ -146,7 +152,7 @@ class Petal(models.Model):
cut = models.ForeignKey(CUT, on_delete=models.CASCADE)
partner = models.ForeignKey(Partner, on_delete=models.CASCADE)
- def __unicode__(self):
+ def __str__(self):
return u'%s/%s/%s' % (self.partner.name, self.cut.uuid, self.name)
def clean(self):
@@ -187,6 +193,7 @@ class Petal(models.Model):
verbose_name_plural = _('Petals')
+@six.python_2_unicode_compatible
class AccessControlList(models.Model):
order = models.IntegerField(
_('Order'))
@@ -208,7 +215,7 @@ class AccessControlList(models.Model):
max_length=128,
default='*')
- def __unicode__(self):
+ def __str__(self):
return u'%s %s %s %s' % (
self.partner.name, self.user.username, self.methods, self.key)
diff --git a/petale/settings.py b/petale/settings.py
index eff3289..a0e6875 100644
--- a/petale/settings.py
+++ b/petale/settings.py
@@ -155,4 +155,6 @@ local_settings_file = os.environ.get(
'PETALE_SETTINGS_FILE',
os.path.join(os.path.dirname(__file__), 'local_settings.py'))
if os.path.exists(local_settings_file):
- execfile(local_settings_file)
+ with open(local_settings_file) as fd:
+ exec(fd.read())
+
diff --git a/petale/utils.py b/petale/utils.py
index 5d6a2f9..d80a75e 100644
--- a/petale/utils.py
+++ b/petale/utils.py
@@ -50,6 +50,8 @@ def etag(stream):
if hasattr(stream, 'chunks'):
for chunk in stream.chunks():
digest.update(chunk)
+ elif hasattr(stream, 'isdecimal'):
+ digest.update(stream.encode('utf-8'))
else:
digest.update(stream)
return '"%s:%s"' % (DEFAULT_HASH_ALGO, digest.hexdigest())
diff --git a/setup.py b/setup.py
index 38aca6d..1ca3a67 100644
--- a/setup.py
+++ b/setup.py
@@ -28,27 +28,38 @@ class eo_sdist(sdist):
def get_version():
+ '''Use the VERSION, if absent generates a version with git describe, if not
+ tag exists, take 0.0- and add the length of the commit log.
+ '''
if os.path.exists('VERSION'):
- version_file = open('VERSION', 'r')
- version = version_file.read()
- version_file.close()
- return version
+ with open('VERSION', 'r') as v:
+ return v.read()
if os.path.exists('.git'):
- p = subprocess.Popen(['git', 'describe', '--dirty', '--match=v*'], stdout=subprocess.PIPE)
+ p = subprocess.Popen(
+ ['git', 'describe', '--dirty=.dirty', '--match=v*'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = p.communicate()[0]
if p.returncode == 0:
- version = result.split()[0][1:]
- version = version.replace('-', '.').replace('.g', '+g')
+ result = result.decode('ascii').strip()[1:] # strip spaces/newlines and initial v
+ if '-' in result: # not a tagged version
+ real_number, commit_count, commit_hash = result.split('-', 2)
+ version = '%s.post%s+%s' % (real_number, commit_count, commit_hash)
+ else:
+ version = result
return version
- return '0'
+ else:
+ return '0.0.post%s' % len(
+ subprocess.check_output(
+ ['git', 'rev-list', 'HEAD']).splitlines())
+ return '0.0'
def data_tree(destdir, sourcedir):
extensions = ['.css', '.png', '.jpeg', '.jpg', '.gif', '.xml', '.html', '.js']
r = []
for root, dirs, files in os.walk(sourcedir):
- l = [os.path.join(root, x) for x in files if os.path.splitext(x)[1] in extensions]
- r.append((root.replace(sourcedir, destdir, 1), l))
+ paths = [os.path.join(root, x) for x in files if os.path.splitext(x)[1] in extensions]
+ r.append((root.replace(sourcedir, destdir, 1), paths))
return r
diff --git a/tests/conftest.py b/tests/conftest.py
index 4c5e5a9..eb53fef 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from tempfile import mkdtemp
import shutil
@@ -76,7 +78,7 @@ def acl(db, partner_southpark, partner_gotham):
def petal_books(db, cut_kevin_uuid, partner_southpark):
name = 'books'
content_type = 'application/json'
- data = '{"books": [{"1984": "U all doomed"}, {"Candide": "Another naive boy"}]}'
+ data = b'{"books": [{"1984": "U all doomed"}, {"Candide": "Another naive boy"}]}'
return create_petal(cut_kevin_uuid, partner_southpark, name, data, content_type)
diff --git a/tests/test_api.py b/tests/test_api.py
index d15e052..ef77ffa 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -131,7 +131,7 @@ def test_simple_api(app, partner_southpark, cut_kevin_uuid, acl, petal_invoice):
# test key deletion
resp = app.delete(url, status=204)
- assert resp.content == ''
+ assert resp.content == b''
app.get(url, status=404)
# test keys purge
diff --git a/tests/utils.py b/tests/utils.py
index ac99967..a25e0c1 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -1,6 +1,6 @@
import os
import json
-from StringIO import StringIO
+from io import BytesIO
import pytest
import mock
@@ -18,7 +18,7 @@ def get_tests_file(filename):
def get_tests_file_content(filename):
- return file(get_tests_file(filename)).read()
+ return open(get_tests_file(filename), 'rb').read()
def create_service(name, password=None):
@@ -55,7 +55,7 @@ def create_petal(cut_uuid, partner, name, data, content_type):
name=name,
size=len(data),
etag=etag(data),
- data=File(StringIO(data), name),
+ data=File(BytesIO(data), name),
content_type=content_type
)