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 )