add compatibility with python 3 (#25486)
This commit is contained in:
parent
9751386861
commit
67931d2d78
|
@ -16,6 +16,7 @@
|
|||
|
||||
from django import template
|
||||
from django.db.models.fields.files import ImageFieldFile
|
||||
from django.utils import six
|
||||
|
||||
from sorl.thumbnail.shortcuts import get_thumbnail
|
||||
|
||||
|
@ -36,7 +37,7 @@ def asset_url(*args, **kwargs):
|
|||
asset = asset_object
|
||||
break
|
||||
|
||||
if isinstance(asset_object, basestring):
|
||||
if isinstance(asset_object, six.string_types):
|
||||
try:
|
||||
asset = Asset.objects.get(key=asset_object).asset
|
||||
break
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
|
||||
import datetime
|
||||
import math
|
||||
import urllib
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from django.utils.dateparse import parse_datetime
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.timezone import localtime, make_aware
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -39,7 +38,7 @@ def get_wcs_services():
|
|||
|
||||
|
||||
def get_chrono_service():
|
||||
for chrono_key, chrono_site in get_services('chrono').iteritems():
|
||||
for chrono_key, chrono_site in get_services('chrono').items():
|
||||
if not chrono_site.get('secondary', True):
|
||||
chrono_site['slug'] = chrono_key
|
||||
return chrono_site
|
||||
|
@ -128,7 +127,7 @@ def get_form_url_with_params(cell, data):
|
|||
}
|
||||
wcs_key, wcs_slug = cell.formdef_reference.split(':')
|
||||
wcs = get_wcs_services().get(wcs_key)
|
||||
url = '%s%s/?%s' % (wcs['url'], wcs_slug, urllib.urlencode(session_vars))
|
||||
url = '%s%s/?%s' % (wcs['url'], wcs_slug, urlencode(session_vars))
|
||||
return url
|
||||
|
||||
|
||||
|
@ -189,7 +188,7 @@ class Calendar(object):
|
|||
"""return the first available slot that has enough
|
||||
consecutive available slots to be allowed for booking
|
||||
"""
|
||||
required_contiguous_slots = self.min_duration.seconds / self.offset.seconds
|
||||
required_contiguous_slots = self.min_duration.seconds // self.offset.seconds
|
||||
for day in self.days:
|
||||
slots = day.slots
|
||||
for idx in range(len(slots) - required_contiguous_slots):
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
from django.contrib import messages
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.encoding import force_text
|
||||
from django.views.generic import View, DetailView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
|
||||
|
@ -36,7 +37,7 @@ class BookingView(SingleObjectMixin, View):
|
|||
try:
|
||||
form.is_valid()
|
||||
except ValueError as exc:
|
||||
messages.error(request, exc.message)
|
||||
messages.error(request, force_text(exc))
|
||||
redirect_url = '%s?%s' % (
|
||||
cell.page.get_online_url(), request.GET.urlencode())
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
|
|
@ -21,7 +21,7 @@ from combo.utils import requests
|
|||
|
||||
def get_passerelle_service():
|
||||
if hasattr(settings, 'KNOWN_SERVICES') and settings.KNOWN_SERVICES.get('passerelle'):
|
||||
return settings.KNOWN_SERVICES['passerelle'].values()[0]
|
||||
return list(settings.KNOWN_SERVICES['passerelle'].values())[0]
|
||||
|
||||
def is_family_enabled():
|
||||
return get_passerelle_service() and hasattr(settings, 'FAMILY_SERVICE')
|
||||
|
|
|
@ -35,5 +35,5 @@ class Command(BaseCommand):
|
|||
for regie in Regie.objects.exclude(webservice_url=''):
|
||||
try:
|
||||
regie.notify_new_remote_invoices()
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.exception('error while notifying new remote invoices: %s', e)
|
||||
|
|
|
@ -20,6 +20,7 @@ from dateutil import parser as date_parser
|
|||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.db.models import Q
|
||||
from django.utils import six
|
||||
from django.utils.timezone import make_aware
|
||||
from django.views.generic import (CreateView, UpdateView, ListView,
|
||||
DeleteView, TemplateView)
|
||||
|
@ -93,7 +94,10 @@ def download_transactions_csv(request):
|
|||
str(transaction.amount)]
|
||||
for item in transaction.items.all():
|
||||
row.extend([item.subject, str(item.amount)])
|
||||
writer.writerow([unicode(x).encode('utf-8') for x in row])
|
||||
if six.PY3:
|
||||
writer.writerow([x for x in row])
|
||||
else:
|
||||
writer.writerow([unicode(x).encode('utf-8') for x in row])
|
||||
return response
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import urlparse
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
|
@ -36,8 +35,10 @@ from django.utils import timezone, dateparse
|
|||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.formats import localize
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.template.loader import render_to_string
|
||||
|
@ -84,6 +85,7 @@ def build_remote_item(data, regie):
|
|||
no_online_payment_reason=data.get('no_online_payment_reason'))
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Regie(models.Model):
|
||||
label = models.CharField(verbose_name=_('Label'), max_length=64)
|
||||
slug = models.SlugField(unique=True, verbose_name=_('Identifier'),
|
||||
|
@ -127,7 +129,7 @@ class Regie(models.Model):
|
|||
def natural_key(self):
|
||||
return (self.slug,)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.label
|
||||
|
||||
def get_text_on_success(self):
|
||||
|
@ -271,7 +273,7 @@ class Regie(models.Model):
|
|||
return
|
||||
pending_invoices = self.get_remote_pending_invoices()
|
||||
notification_ids = []
|
||||
for uuid, items in pending_invoices.iteritems():
|
||||
for uuid, items in pending_invoices.items():
|
||||
try:
|
||||
user = UserSAMLIdentifier.objects.get(name_id=uuid).user
|
||||
except UserSAMLIdentifier.DoesNotExist:
|
||||
|
@ -534,7 +536,7 @@ class LingoBasketCell(CellBase):
|
|||
for items in regies.values():
|
||||
items['total'] = sum([x.amount for x in items['items']])
|
||||
|
||||
context['regies'] = regies.values()
|
||||
context['regies'] = sorted(regies.values(), key=lambda x: x['regie'].label)
|
||||
return basket_template.render(context)
|
||||
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ class ValidateTransactionApiView(View):
|
|||
except eopayment.ResponseError as e:
|
||||
logger.error(u'failed in validation operation: %s', e)
|
||||
response = HttpResponse(content_type='application/json')
|
||||
response.write(json.dumps({'err': 1, 'e': unicode(e)}))
|
||||
response.write(json.dumps({'err': 1, 'e': force_text(e)}))
|
||||
return response
|
||||
|
||||
logger.info(u'bank validation result: %r', result)
|
||||
|
@ -279,7 +279,7 @@ class CancelTransactionApiView(View):
|
|||
except eopayment.ResponseError as e:
|
||||
logger.error(u'failed in cancel operation: %s', e)
|
||||
response = HttpResponse(content_type='application/json')
|
||||
response.write(json.dumps({'err': 1, 'e': unicode(e)}))
|
||||
response.write(json.dumps({'err': 1, 'e': force_text(e)}))
|
||||
return response
|
||||
|
||||
logger.info(u'bank cancellation result: %r', result)
|
||||
|
@ -414,7 +414,7 @@ class PaymentView(View):
|
|||
'eopayment_order_id': smart_text(payment_response.order_id),
|
||||
'eopayment_response': repr(payment_response),
|
||||
}
|
||||
for k, v in payment_response.bank_data.iteritems():
|
||||
for k, v in payment_response.bank_data.items():
|
||||
extra_info['eopayment_bank_data_' + k] = smart_text(v)
|
||||
if not payment_response.signed and not payment_response.result == eopayment.CANCELLED:
|
||||
# we accept unsigned cancellation requests as some platforms do
|
||||
|
@ -494,9 +494,9 @@ class CallbackView(PaymentView):
|
|||
try:
|
||||
self.handle_response(request, backend_response, **kwargs)
|
||||
except UnknownPaymentException as e:
|
||||
raise Http404(unicode(e))
|
||||
raise Http404(force_text(e))
|
||||
except PaymentException as e:
|
||||
return HttpResponseBadRequest(unicode(e))
|
||||
return HttpResponseBadRequest(force_text(e))
|
||||
return HttpResponse()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
|
|
@ -18,6 +18,8 @@ import json
|
|||
|
||||
from django.core import serializers
|
||||
from django.db import models
|
||||
from django.utils import six
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
|
@ -88,6 +90,7 @@ class MapLayerManager(models.Manager):
|
|||
return self.get(slug=slug)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class MapLayer(models.Model):
|
||||
objects = MapLayerManager()
|
||||
|
||||
|
@ -123,7 +126,7 @@ class MapLayer(models.Model):
|
|||
self.slug = slug
|
||||
super(MapLayer, self).save(*args, **kwargs)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.label
|
||||
|
||||
def natural_key(self):
|
||||
|
@ -204,7 +207,7 @@ class MapLayer(models.Model):
|
|||
|
||||
def match(feature):
|
||||
for geo_property in feature['properties'].values():
|
||||
if not isinstance(geo_property, basestring):
|
||||
if not isinstance(geo_property, six.string_types):
|
||||
continue
|
||||
if query in slugify(geo_property):
|
||||
return True
|
||||
|
|
|
@ -14,13 +14,12 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from urlparse import urlparse
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db import connection
|
||||
from django.test.client import RequestFactory
|
||||
from django.utils import translation
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
|
||||
from combo.apps.momo.utils import generate_manifest, GenerationError, GenerationInfo
|
||||
|
||||
|
@ -46,5 +45,5 @@ class Command(BaseCommand):
|
|||
raise CommandError(e.message)
|
||||
except GenerationInfo as e:
|
||||
if int(kwargs.get('verbosity')) > 0:
|
||||
print e.message
|
||||
print(e.message)
|
||||
translation.deactivate()
|
||||
|
|
|
@ -84,7 +84,7 @@ class MomoIconCell(CellBase):
|
|||
|
||||
def get_default_form_class(self):
|
||||
sorted_icons = self._meta.get_field('icon').choices
|
||||
sorted_icons.sort(lambda x, y: cmp(x[1], y[1]))
|
||||
sorted_icons.sort(key=lambda x: x[1])
|
||||
return model_forms.modelform_factory(self.__class__,
|
||||
fields=['icon', 'style', 'description', 'embed_page'],
|
||||
widgets={'icon': Select(choices=sorted_icons)})
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.encoding import force_text
|
||||
from django.views.generic import TemplateView, UpdateView
|
||||
|
||||
from .models import MomoOptions
|
||||
|
@ -30,9 +31,9 @@ def generate(request, **kwargs):
|
|||
try:
|
||||
generate_manifest(request)
|
||||
except GenerationError as e:
|
||||
messages.error(request, e.message)
|
||||
messages.error(request, force_text(e))
|
||||
except GenerationInfo as e:
|
||||
messages.info(request, e.message)
|
||||
messages.info(request, force_text(e))
|
||||
return HttpResponseRedirect(reverse('momo-manager-homepage'))
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class NewslettersManageForm(forms.Form):
|
|||
self.cleaned_data = {}
|
||||
try:
|
||||
newsletters = self.instance.get_newsletters()
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.add_error(None, _('An error occured while getting newsletters. Please try later.'))
|
||||
logger.error('Error occured while getting newsletters: %r', e)
|
||||
return
|
||||
|
@ -46,7 +46,7 @@ class NewslettersManageForm(forms.Form):
|
|||
self.params['mobile'] = self.request.session['mellon_session'].get('mobile', '')
|
||||
try:
|
||||
subscriptions = self.instance.get_subscriptions(self.user, **self.params)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.add_error(None, _('An error occured while getting subscriptions. Please try later.'))
|
||||
logger.error('Error occured while getting subscriptions: %r', e)
|
||||
return
|
||||
|
@ -75,7 +75,7 @@ class NewslettersManageForm(forms.Form):
|
|||
def save(self):
|
||||
self.full_clean()
|
||||
subscriptions = []
|
||||
for key, value in self.cleaned_data.iteritems():
|
||||
for key, value in self.cleaned_data.items():
|
||||
subscriptions.append({
|
||||
'id': key,
|
||||
'transports': value
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
import logging
|
||||
import json
|
||||
import urlparse
|
||||
|
||||
from requests.exceptions import RequestException, HTTPError
|
||||
|
||||
|
@ -70,10 +69,10 @@ class NewslettersCell(CellBase):
|
|||
return slugify(name.strip())
|
||||
|
||||
def get_resources_restrictions(self):
|
||||
return filter(None, map(self.simplify, self.resources_restrictions.strip().split(',')))
|
||||
return list(filter(None, map(self.simplify, self.resources_restrictions.strip().split(','))))
|
||||
|
||||
def get_transports_restrictions(self):
|
||||
return filter(None, map(self.simplify, self.transports_restrictions.strip().split(',')))
|
||||
return list(filter(None, map(self.simplify, self.transports_restrictions.strip().split(','))))
|
||||
|
||||
def check_resource(self, resource):
|
||||
restrictions = self.get_resources_restrictions()
|
||||
|
@ -130,7 +129,7 @@ class NewslettersCell(CellBase):
|
|||
logger.error(u'set subscriptions on %s returned an HTTP error code: %s',
|
||||
response.request.url, response.status_code)
|
||||
raise SubscriptionsSaveError
|
||||
except RequestException, e:
|
||||
except RequestException as e:
|
||||
logger.error(u'set subscriptions on %s failed with exception: %s',
|
||||
endpoint, e)
|
||||
raise SubscriptionsSaveError
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from rest_framework import serializers, permissions, status
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.response import Response
|
||||
|
@ -55,7 +57,7 @@ class Add(GenericAPIView):
|
|||
duration=data.get('duration'),
|
||||
)
|
||||
except ValueError as e:
|
||||
response = {'err': 1, 'err_desc': {'id': [unicode(e)]}}
|
||||
response = {'err': 1, 'err_desc': {'id': [force_text(e)]}}
|
||||
return Response(response, status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
response = {'err': 0, 'data': {'id': notification.public_id}}
|
||||
|
|
|
@ -18,6 +18,7 @@ import re
|
|||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.timezone import now, timedelta
|
||||
from django.db.models import Q
|
||||
|
@ -61,6 +62,7 @@ class NotificationQuerySet(QuerySet):
|
|||
end_timestamp=past_end_timestamp, acked=True)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Notification(models.Model):
|
||||
ID_RE = r'^[\w-]+:[\w-]+$'
|
||||
|
||||
|
@ -82,7 +84,7 @@ class Notification(models.Model):
|
|||
('user', 'external_id'),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.summary
|
||||
|
||||
@property
|
||||
|
@ -136,7 +138,7 @@ class Notification(models.Model):
|
|||
|
||||
if id:
|
||||
try:
|
||||
id = unicode(id)
|
||||
id = force_text(id)
|
||||
except Exception as e:
|
||||
raise ValueError('id must be convertible to unicode', e)
|
||||
if not re.match(cls.ID_RE, id):
|
||||
|
|
|
@ -500,6 +500,6 @@ class TrackingCodeInputCell(CellBase):
|
|||
def get_cell_extra_context(self, context):
|
||||
extra_context = super(TrackingCodeInputCell, self).get_cell_extra_context(context)
|
||||
if not self.wcs_site:
|
||||
self.wcs_site = get_wcs_services().keys()[0]
|
||||
self.wcs_site = list(get_wcs_services().keys())[0]
|
||||
extra_context['url'] = get_wcs_services().get(self.wcs_site).get('url')
|
||||
return extra_context
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load i18n combo %}
|
||||
{% block cell-content %}
|
||||
<h2>{% trans 'Current Drafts' %}</h2>
|
||||
{% for slug, forms in current_drafts.iteritems %}
|
||||
{% for slug, forms in current_drafts.items %}
|
||||
<div class="current-drafts-{{ slug }} current-drafts list-of-forms">
|
||||
{% if forms.data %}
|
||||
<ul>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load i18n %}
|
||||
{% block cell-content %}
|
||||
<h2>{% trans 'Current Forms' %}</h2>
|
||||
{% for slug, forms in current_forms.iteritems %}
|
||||
{% for slug, forms in current_forms.items %}
|
||||
<div class="current-forms-{{ slug }} current-forms list-of-forms">
|
||||
{% include "combo/wcs/list_of_forms.html" with forms=forms %}
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load i18n %}
|
||||
{% block cell-content %}
|
||||
<h2>{% trans 'Form Categories' %}</h2>
|
||||
{% for slug, categories in form_categories.iteritems %}
|
||||
{% for slug, categories in form_categories.items %}
|
||||
<div class="categories-{{ slug }}">
|
||||
<h3>{{ categories.title }}</h3>
|
||||
<ul>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load combo i18n %}
|
||||
{% block cell-content %}
|
||||
<h2>{% trans 'All Forms' %}</h2>
|
||||
{% for slug, forms in user_forms.iteritems %}
|
||||
{% for slug, forms in user_forms.items %}
|
||||
<div class="user-forms-{{ slug }} user-all-forms list-of-forms">
|
||||
{% include "combo/wcs/list_of_forms.html" with forms=forms %}
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load combo i18n %}
|
||||
{% block cell-content %}
|
||||
<h2>{% trans 'Done Forms' %}</h2>
|
||||
{% for slug, forms in user_forms.iteritems %}
|
||||
{% for slug, forms in user_forms.items %}
|
||||
<div class="user-forms-{{ slug }} list-of-forms">
|
||||
{% include "combo/wcs/list_of_forms.html" with forms=forms %}
|
||||
</div>
|
||||
|
|
|
@ -32,7 +32,7 @@ def get_wcs_json(wcs_site, path):
|
|||
|
||||
def get_wcs_options(url, include_category_slug=False):
|
||||
references = []
|
||||
for wcs_key, wcs_site in get_wcs_services().iteritems():
|
||||
for wcs_key, wcs_site in get_wcs_services().items():
|
||||
site_title = wcs_site.get('title')
|
||||
response_json = get_wcs_json(wcs_site, url)
|
||||
if type(response_json) is dict:
|
||||
|
@ -51,5 +51,5 @@ def get_wcs_options(url, include_category_slug=False):
|
|||
else:
|
||||
reference = '%s:%s' % (wcs_key, slug)
|
||||
references.append((reference, label))
|
||||
references.sort(lambda x, y: cmp(x[1], y[1]))
|
||||
references.sort(key=lambda x: x[1])
|
||||
return references
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import urlparse
|
||||
|
||||
from django.contrib import messages
|
||||
from django.http import HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import View
|
||||
|
|
|
@ -18,6 +18,7 @@ import json
|
|||
import sys
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from combo.data.utils import import_site, MissingGroups
|
||||
|
||||
|
@ -44,4 +45,4 @@ class Command(BaseCommand):
|
|||
if_empty=options['if_empty'],
|
||||
clean=options['clean'])
|
||||
except MissingGroups as e:
|
||||
print >> sys.stderr, unicode(e)
|
||||
sys.stderr.write(force_text(e) + '\n')
|
||||
|
|
|
@ -24,7 +24,6 @@ import os
|
|||
import re
|
||||
import requests
|
||||
import subprocess
|
||||
import urlparse
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
|
@ -40,9 +39,11 @@ from django.dispatch import receiver
|
|||
from django.forms import models as model_forms
|
||||
from django import forms
|
||||
from django import template
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils import six
|
||||
from django.utils.encoding import python_2_unicode_compatible, force_text, smart_bytes
|
||||
from django.utils.html import strip_tags
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.forms.widgets import MediaDefiningClass
|
||||
|
@ -116,6 +117,7 @@ class PageManager(models.Manager):
|
|||
return queryset.filter(snapshot__isnull=True)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Page(models.Model):
|
||||
objects = PageManager()
|
||||
snapshots = PageManager(snapshots=True)
|
||||
|
@ -149,7 +151,7 @@ class Page(models.Model):
|
|||
class Meta:
|
||||
ordering = ['order']
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def natural_key(self):
|
||||
|
@ -349,7 +351,7 @@ class Page(models.Model):
|
|||
del cell['pk']
|
||||
del cell['fields']['page']
|
||||
cell['fields']['groups'] = [x[0] for x in cell['fields']['groups']]
|
||||
for key in cell['fields'].keys():
|
||||
for key in list(cell['fields'].keys()):
|
||||
if key.startswith('cached_'):
|
||||
del cell['fields'][key]
|
||||
return serialized_page
|
||||
|
@ -357,14 +359,14 @@ class Page(models.Model):
|
|||
@classmethod
|
||||
def load_serialized_page(cls, json_page, snapshot=None):
|
||||
json_page['model'] = 'data.page'
|
||||
json_page['fields']['groups'] = [[x] for x in json_page['fields']['groups'] if isinstance(x, basestring)]
|
||||
json_page['fields']['groups'] = [[x] for x in json_page['fields']['groups'] if isinstance(x, six.string_types)]
|
||||
page, created = Page.objects.get_or_create(slug=json_page['fields']['slug'], snapshot=snapshot)
|
||||
json_page['pk'] = page.id
|
||||
page = [x for x in serializers.deserialize('json', json.dumps([json_page]))][0]
|
||||
page.object.snapshot = snapshot
|
||||
page.save()
|
||||
for cell in json_page.get('cells'):
|
||||
cell['fields']['groups'] = [[x] for x in cell['fields']['groups'] if isinstance(x, basestring)]
|
||||
cell['fields']['groups'] = [[x] for x in cell['fields']['groups'] if isinstance(x, six.string_types)]
|
||||
if snapshot:
|
||||
cell['fields']['page'] = page.object.id
|
||||
else:
|
||||
|
@ -462,8 +464,8 @@ class CellMeta(MediaDefiningClass, ModelBase):
|
|||
pass
|
||||
|
||||
|
||||
class CellBase(models.Model):
|
||||
__metaclass__ = CellMeta
|
||||
@python_2_unicode_compatible
|
||||
class CellBase(six.with_metaclass(CellMeta, models.Model)):
|
||||
|
||||
page = models.ForeignKey(Page)
|
||||
placeholder = models.CharField(max_length=20)
|
||||
|
@ -499,13 +501,13 @@ class CellBase(models.Model):
|
|||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __unicode__(self):
|
||||
label = unicode(self.get_verbose_name())
|
||||
def __str__(self):
|
||||
label = self.get_verbose_name()
|
||||
additional_label = self.get_additional_label()
|
||||
if label and additional_label:
|
||||
return '%s (%s)' % (label, re.sub(r'\r?\n', ' ', force_text(additional_label)))
|
||||
return u'%s (%s)' % (label, re.sub(r'\r?\n', u' ', force_text(additional_label)))
|
||||
else:
|
||||
return label
|
||||
return force_text(label)
|
||||
|
||||
@classmethod
|
||||
def get_verbose_name(cls):
|
||||
|
@ -561,7 +563,7 @@ class CellBase(models.Model):
|
|||
if cell_filter and not cell_filter(klass):
|
||||
continue
|
||||
cells.extend(klass.objects.filter(**kwargs))
|
||||
cells.sort(lambda x, y: cmp(x.order, y.order))
|
||||
cells.sort(key=lambda x: x.order)
|
||||
return cells
|
||||
|
||||
def get_reference(self):
|
||||
|
@ -699,7 +701,7 @@ class CellBase(models.Model):
|
|||
}
|
||||
if not self.is_relevant(context):
|
||||
return ''
|
||||
from HTMLParser import HTMLParser
|
||||
from django.utils.six.moves.html_parser import HTMLParser
|
||||
return HTMLParser().unescape(strip_tags(self.render(context)))
|
||||
|
||||
def get_external_links_data(self):
|
||||
|
@ -832,7 +834,7 @@ class LinkCell(CellBase):
|
|||
return context
|
||||
|
||||
def get_default_form_class(self):
|
||||
from forms import LinkCellForm
|
||||
from .forms import LinkCellForm
|
||||
return LinkCellForm
|
||||
|
||||
def render_for_search(self):
|
||||
|
@ -867,7 +869,7 @@ class FeedCell(CellBase):
|
|||
if context.get('placeholder_search_mode'):
|
||||
# don't call webservices when we're just looking for placeholders
|
||||
return extra_context
|
||||
cache_key = hashlib.md5(self.url).hexdigest()
|
||||
cache_key = hashlib.md5(smart_bytes(self.url)).hexdigest()
|
||||
feed_content = cache.get(cache_key)
|
||||
if not feed_content:
|
||||
feed_response = requests.get(utils.get_templated_url(self.url))
|
||||
|
@ -886,7 +888,7 @@ class FeedCell(CellBase):
|
|||
return extra_context
|
||||
|
||||
def render(self, context):
|
||||
cache_key = hashlib.md5(self.url).hexdigest()
|
||||
cache_key = hashlib.md5(smart_bytes(self.url)).hexdigest()
|
||||
feed_content = cache.get(cache_key)
|
||||
if not context.get('synchronous') and feed_content is None:
|
||||
raise NothingInCacheException()
|
||||
|
@ -1091,13 +1093,13 @@ class JsonCellBase(CellBase):
|
|||
)
|
||||
except requests.RequestException as e:
|
||||
extra_context[data_key + '_status'] = -1
|
||||
extra_context[data_key + '_error'] = unicode(e)
|
||||
extra_context[data_key + '_error'] = force_text(e)
|
||||
extra_context[data_key + '_exception'] = e
|
||||
logger = logging.getLogger(__name__)
|
||||
if log_errors:
|
||||
logger.warning(u'error on request %r: %s', url, unicode(e))
|
||||
logger.warning(u'error on request %r: %s', url, force_text(e))
|
||||
else:
|
||||
logger.debug(u'error on request %r: %s', url, unicode(e))
|
||||
logger.debug(u'error on request %r: %s', url, force_text(e))
|
||||
continue
|
||||
extra_context[data_key + '_status'] = json_response.status_code
|
||||
if json_response.status_code // 100 == 2:
|
||||
|
@ -1243,7 +1245,7 @@ class ConfigJsonCell(JsonCellBase):
|
|||
'group': _('Extra'),
|
||||
'cell_type_str': cls.get_cell_type_str(),
|
||||
})
|
||||
l.sort(lambda x, y: cmp(x.get('name'), y.get('name')))
|
||||
l.sort(key=lambda x: x.get('name'))
|
||||
return l
|
||||
|
||||
def get_label(self):
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db import transaction
|
||||
from django.utils import six
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from combo.apps.assets.models import Asset
|
||||
|
@ -23,11 +25,12 @@ from combo.apps.maps.models import MapLayer
|
|||
from .models import Page
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class MissingGroups(Exception):
|
||||
def __init__(self, names):
|
||||
self.names = names
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return _('Missing groups: %s') % ', '.join(self.names)
|
||||
|
||||
|
||||
|
@ -51,10 +54,10 @@ def import_site(data, if_empty=False, clean=False):
|
|||
groups = set()
|
||||
for page in data.get('pages') or []:
|
||||
for group in page['fields']['groups']:
|
||||
groups.add(group if isinstance(group, basestring) else group[0])
|
||||
groups.add(group if isinstance(group, six.string_types) else group[0])
|
||||
for cell in page['cells']:
|
||||
for group in cell['fields']['groups']:
|
||||
groups.add(group if isinstance(group, basestring) else group[0])
|
||||
groups.add(group if isinstance(group, six.string_types) else group[0])
|
||||
|
||||
existing_groups = set([x.name for x in Group.objects.filter(name__in=groups)])
|
||||
missing_groups = groups - existing_groups
|
||||
|
|
|
@ -69,7 +69,7 @@ class PageSelectTemplateForm(forms.ModelForm):
|
|||
super(PageSelectTemplateForm, self).__init__(*args, **kwargs)
|
||||
templates = [(x[0], x[1]['name']) for x in settings.COMBO_PUBLIC_TEMPLATES.items()]
|
||||
templates = [x for x in templates if self.template_exists(x[0])]
|
||||
templates.sort(lambda x, y: cmp(x[1], y[1]))
|
||||
templates.sort(key=lambda x: x[1])
|
||||
if 'template_name' in self.fields:
|
||||
self.fields['template_name'].widget = forms.Select(choices=templates)
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ class PageView(DetailView):
|
|||
if 'data' in cell_type_groups.keys():
|
||||
cell_type_groups[''] = cell_type_groups.get('data')
|
||||
del cell_type_groups['data']
|
||||
context['cell_type_groups'] = cell_type_groups.items()
|
||||
context['cell_type_groups'] = list(cell_type_groups.items())
|
||||
context['cell_type_groups'].sort(key=lambda x: x[0])
|
||||
|
||||
cells = CellBase.get_cells(page_id=self.object.id)
|
||||
|
|
|
@ -220,3 +220,7 @@ def get_group(group_list, group_name):
|
|||
@register.filter(name='is_empty_placeholder')
|
||||
def is_empty_placeholder(page, placeholder_name):
|
||||
return len([x for x in page.get_cells() if x.placeholder == placeholder_name]) == 0
|
||||
|
||||
@register.filter(name='list')
|
||||
def as_list(obj):
|
||||
return list(obj)
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
|
@ -31,6 +29,9 @@ from django.shortcuts import render, resolve_url
|
|||
from django.template import engines
|
||||
from django.template.loader import get_template, TemplateDoesNotExist
|
||||
from django.utils import lorem_ipsum, timezone
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from django.utils.six.moves.urllib import parse as urllib
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
@ -102,14 +103,14 @@ def ajax_page_cell(request, page_pk, cell_reference):
|
|||
except PostException as e:
|
||||
exception = e
|
||||
if not request.is_ajax():
|
||||
messages.error(request, e.message or _('Error sending data.'))
|
||||
messages.error(request, force_text(e) if force_text(e) != 'None' else _('Error sending data.'))
|
||||
|
||||
if not request.is_ajax():
|
||||
return HttpResponseRedirect(cell.page.get_online_url())
|
||||
|
||||
response = render_cell(request, cell)
|
||||
if exception:
|
||||
response['x-error-message'] = exception.message
|
||||
response['x-error-message'] = force_text(exception)
|
||||
return response
|
||||
|
||||
def render_cell(request, cell):
|
||||
|
|
|
@ -315,4 +315,4 @@ NEWSLETTERS_CELL_ENABLED = False
|
|||
local_settings_file = os.environ.get('COMBO_SETTINGS_FILE',
|
||||
os.path.join(os.path.dirname(__file__), 'local_settings.py'))
|
||||
if os.path.exists(local_settings_file):
|
||||
execfile(local_settings_file)
|
||||
exec(open(local_settings_file).read())
|
||||
|
|
|
@ -20,6 +20,9 @@ from Crypto.Cipher import AES
|
|||
from Crypto.Protocol.KDF import PBKDF2
|
||||
from Crypto import Random
|
||||
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
|
||||
class DecryptionError(Exception):
|
||||
pass
|
||||
|
@ -33,7 +36,7 @@ def aes_hex_encrypt(key, data):
|
|||
aes_key = PBKDF2(key, iv)
|
||||
aes = AES.new(aes_key, AES.MODE_CFB, iv)
|
||||
crypted = aes.encrypt(data)
|
||||
return '%s%s' % (binascii.hexlify(iv[:2]), binascii.hexlify(crypted))
|
||||
return force_text(b'%s%s' % (binascii.hexlify(iv[:2]), binascii.hexlify(crypted)))
|
||||
|
||||
def aes_hex_decrypt(key, payload, raise_on_error=True):
|
||||
'''Decrypt data encrypted with aes_base64_encrypt'''
|
||||
|
@ -46,10 +49,10 @@ def aes_hex_decrypt(key, payload, raise_on_error=True):
|
|||
try:
|
||||
iv = binascii.unhexlify(iv) * 8
|
||||
crypted = binascii.unhexlify(crypted)
|
||||
except TypeError:
|
||||
except (TypeError, binascii.Error):
|
||||
if raise_on_error:
|
||||
raise DecryptionError('incorrect hexadecimal encoding')
|
||||
return None
|
||||
aes_key = PBKDF2(key, iv)
|
||||
aes = AES.new(aes_key, AES.MODE_CFB, iv)
|
||||
return aes.decrypt(crypted)
|
||||
return force_text(aes.decrypt(crypted), 'utf-8')
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from HTMLParser import HTMLParser
|
||||
from django.utils.six.moves.html_parser import HTMLParser
|
||||
|
||||
from django.template.context import BaseContext
|
||||
from django.utils.html import strip_tags
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
import hashlib
|
||||
import logging
|
||||
from StringIO import StringIO
|
||||
import urlparse
|
||||
|
||||
from requests import Response, Session as RequestsSession
|
||||
|
||||
|
@ -25,6 +23,8 @@ from django.conf import settings
|
|||
from django.core.cache import cache
|
||||
from django.utils.encoding import smart_bytes
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
from django.utils.six import BytesIO
|
||||
|
||||
from .signature import sign_url
|
||||
|
||||
|
@ -110,7 +110,7 @@ class Requests(RequestsSession):
|
|||
if cache_content and not invalidate_cache:
|
||||
response = Response()
|
||||
response.status_code = 200
|
||||
response.raw = StringIO(cache_content)
|
||||
response.raw = BytesIO(smart_bytes(cache_content))
|
||||
return response
|
||||
elif raise_if_not_cached:
|
||||
raise NothingInCacheException()
|
||||
|
|
|
@ -19,10 +19,13 @@ import datetime
|
|||
import hmac
|
||||
import hashlib
|
||||
import random
|
||||
import urlparse
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import smart_bytes
|
||||
from django.utils.http import quote, urlencode
|
||||
from django.utils import six
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
|
||||
|
||||
# Simple signature scheme for query strings
|
||||
|
||||
|
@ -50,7 +53,7 @@ def sign_query(query, key, algo='sha256', timestamp=None, nonce=None):
|
|||
|
||||
def sign_string(s, key, algo='sha256', timedelta=30):
|
||||
digestmod = getattr(hashlib, algo)
|
||||
hash = hmac.HMAC(str(key), digestmod=digestmod, msg=s)
|
||||
hash = hmac.HMAC(smart_bytes(key), digestmod=digestmod, msg=smart_bytes(s))
|
||||
return hash.digest()
|
||||
|
||||
def check_request_signature(django_request, keys=[]):
|
||||
|
@ -60,8 +63,8 @@ def check_request_signature(django_request, keys=[]):
|
|||
orig = django_request.GET.get('orig', '')
|
||||
known_services = getattr(settings, 'KNOWN_SERVICES', None)
|
||||
if known_services and orig:
|
||||
for services in known_services.itervalues():
|
||||
for service in services.itervalues():
|
||||
for services in known_services.values():
|
||||
for service in services.values():
|
||||
if 'verif_orig' in service and service['verif_orig'] == orig:
|
||||
keys.append(service['secret'])
|
||||
break
|
||||
|
@ -95,8 +98,12 @@ def check_string(s, signature, keys, algo='sha256'):
|
|||
continue
|
||||
res = 0
|
||||
# constant time compare
|
||||
for a, b in zip(signature, signature2):
|
||||
res |= ord(a) ^ ord(b)
|
||||
if six.PY3:
|
||||
for a, b in zip(signature, signature2):
|
||||
res |= a ^ b
|
||||
else:
|
||||
for a, b in zip(signature, signature2):
|
||||
res |= ord(a) ^ ord(b)
|
||||
if res == 0:
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import force_text
|
||||
from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist
|
||||
from django.utils.http import quote
|
||||
|
||||
|
@ -58,5 +59,5 @@ def get_templated_url(url, context=None):
|
|||
return '['
|
||||
if varname not in template_vars:
|
||||
raise TemplateError('unknown variable %s', varname)
|
||||
return unicode(template_vars[varname])
|
||||
return force_text(template_vars[varname])
|
||||
return re.sub(r'(\[.+?\])', repl, url)
|
||||
|
|
2
setup.py
2
setup.py
|
@ -36,7 +36,7 @@ def get_version():
|
|||
p = subprocess.Popen(['git', 'describe', '--dirty', '--match=v*'], stdout=subprocess.PIPE)
|
||||
result = p.communicate()[0]
|
||||
if p.returncode == 0:
|
||||
version = result.split()[0][1:]
|
||||
version = str(result.split()[0][1:])
|
||||
version = version.replace('-', '.')
|
||||
return version
|
||||
return '0'
|
||||
|
|
8
tox.ini
8
tox.ini
|
@ -1,12 +1,12 @@
|
|||
[tox]
|
||||
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/combo/{env:BRANCH_NAME:}
|
||||
envlist = django{18,111}
|
||||
envlist = py2-django18,coverage-py2-django111-pylint,py3-django111
|
||||
|
||||
[testenv]
|
||||
usedevelop = True
|
||||
basepython = python2
|
||||
setenv =
|
||||
WCSCTL=wcs/wcsctl.py
|
||||
py2: WCSCTL=wcs/wcsctl.py
|
||||
DJANGO_SETTINGS_MODULE=combo.settings
|
||||
COMBO_SETTINGS_FILE=tests/settings.py
|
||||
deps =
|
||||
|
@ -22,10 +22,10 @@ deps =
|
|||
pylint<1.8
|
||||
pylint-django<0.9
|
||||
django-webtest<1.9.3
|
||||
quixote<3.0
|
||||
vobject
|
||||
psycopg2
|
||||
django-mellon
|
||||
py2: quixote<3.0
|
||||
py2: vobject
|
||||
commands =
|
||||
./getlasso.sh
|
||||
python manage.py compilemessages
|
||||
|
|
Loading…
Reference in New Issue