Upgrade requirements.txt
parent
386893f2e4
commit
c698b0798b
|
@ -1,13 +1,11 @@
|
||||||
-r requirements.txt
|
-r requirements.txt
|
||||||
|
|
||||||
factory_boy==2.8.1
|
coverage==4.4.1
|
||||||
py==1.4.32
|
|
||||||
pytest==3.0.6
|
|
||||||
pytest-django==3.1.2
|
|
||||||
pytest-pythonpath==0.7.1
|
|
||||||
|
|
||||||
coverage==4.3.4
|
|
||||||
coveralls==1.1
|
coveralls==1.1
|
||||||
django-slowdown==0.0.1
|
django-slowdown==0.0.1
|
||||||
|
factory_boy==2.8.1
|
||||||
|
py==1.4.34
|
||||||
|
pytest-django==3.1.2
|
||||||
|
pytest-pythonpath==0.7.1
|
||||||
|
pytest==3.1.1
|
||||||
transifex-client==0.12.4
|
transifex-client==0.12.4
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
Django==1.10.6
|
|
||||||
#djangorestframework==2.3.13 # It's not necessary since Taiga 1.7
|
#djangorestframework==2.3.13 # It's not necessary since Taiga 1.7
|
||||||
|
CairoSVG==2.0.3
|
||||||
|
Django==1.11.2
|
||||||
|
Markdown==2.6.8
|
||||||
|
Pillow==4.1.1
|
||||||
|
PyJWT==1.5.0
|
||||||
|
Unidecode==0.4.20
|
||||||
|
amqp==2.1.4
|
||||||
|
asana==0.6.5
|
||||||
|
bleach==2.0.0
|
||||||
|
celery==4.0.2
|
||||||
|
cryptography==1.9
|
||||||
|
cssutils==1.0.2
|
||||||
|
diff-match-patch==20121119
|
||||||
|
django-ipware==1.1.6
|
||||||
|
django-jinja==2.3.1
|
||||||
django-picklefield==0.3.2
|
django-picklefield==0.3.2
|
||||||
django-sampledatahelper==0.4.1
|
django-sampledatahelper==0.4.1
|
||||||
gunicorn==19.6.0
|
|
||||||
psycopg2==2.7
|
|
||||||
Pillow==3.4.2
|
|
||||||
pytz==2016.10
|
|
||||||
six==1.10.0
|
|
||||||
amqp==2.1.4
|
|
||||||
djmail==1.0.1
|
|
||||||
django-jinja==2.2.2
|
|
||||||
jinja2==2.9.5
|
|
||||||
pygments==2.2.0
|
|
||||||
django-sites==0.9
|
django-sites==0.9
|
||||||
Markdown==2.6.8
|
|
||||||
fn==0.4.3
|
|
||||||
diff-match-patch==20121119
|
|
||||||
requests==2.13.0
|
|
||||||
requests-oauthlib==0.8.0
|
|
||||||
webcolors==1.7
|
|
||||||
django-sr==0.0.4
|
django-sr==0.0.4
|
||||||
easy-thumbnails==2.3
|
djmail==1.0.1
|
||||||
celery==4.0.2
|
easy-thumbnails==2.4.1
|
||||||
redis==2.10.5
|
fn==0.4.3
|
||||||
Unidecode==0.4.20
|
|
||||||
raven==6.0.0
|
|
||||||
bleach==1.5.0
|
|
||||||
django-ipware==1.1.6
|
|
||||||
premailer==3.0.1
|
|
||||||
cssutils==1.0.1 # Compatible with python 3.5
|
|
||||||
lxml==3.7.3
|
|
||||||
git+https://github.com/Xof/django-pglocks.git
|
git+https://github.com/Xof/django-pglocks.git
|
||||||
|
gunicorn==19.7.1
|
||||||
|
jinja2==2.9.6
|
||||||
|
lxml==3.8.0
|
||||||
|
netaddr==0.7.19
|
||||||
|
premailer==3.0.1
|
||||||
|
psd-tools==1.4
|
||||||
|
psycopg2==2.7.1
|
||||||
|
pygments==2.2.0
|
||||||
pyjwkest==1.3.2
|
pyjwkest==1.3.2
|
||||||
python-dateutil==2.6.0
|
python-dateutil==2.6.0
|
||||||
netaddr==0.7.19
|
|
||||||
serpy==0.1.1
|
|
||||||
psd-tools==1.4
|
|
||||||
CairoSVG==2.0.1
|
|
||||||
python-magic==0.4.13
|
python-magic==0.4.13
|
||||||
cryptography==1.7.1
|
pytz==2017.2
|
||||||
PyJWT==1.4.2
|
raven==6.1.0
|
||||||
asana==0.6.2
|
redis==2.10.5
|
||||||
|
requests-oauthlib==0.8.0
|
||||||
|
requests==2.17.3
|
||||||
|
serpy==0.1.1
|
||||||
|
six==1.10.0
|
||||||
|
webcolors==1.7
|
||||||
|
|
|
@ -456,7 +456,6 @@ class APIView(View):
|
||||||
handler = self.http_method_not_allowed
|
handler = self.http_method_not_allowed
|
||||||
|
|
||||||
response = handler(request, *args, **kwargs)
|
response = handler(request, *args, **kwargs)
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
response = self.handle_exception(exc)
|
response = self.handle_exception(exc)
|
||||||
|
|
||||||
|
|
|
@ -20,63 +20,10 @@
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.contrib.postgres.fields import JSONField as DjangoJSONField
|
from django.contrib.postgres.fields import JSONField as DjangoJSONField
|
||||||
|
|
||||||
# NOTE: After upgrade Django to the future release (1.11) change
|
|
||||||
# class JSONField(FutureDjangoJSONField):
|
|
||||||
# to
|
|
||||||
# class JSONField(DjangoJSONField):
|
|
||||||
# and remove the classes JsonAdapter and FutureDjangoJSONField
|
|
||||||
|
|
||||||
import json
|
|
||||||
from psycopg2.extras import Json
|
|
||||||
from django.core import exceptions
|
|
||||||
|
|
||||||
|
|
||||||
class JsonAdapter(Json):
|
|
||||||
"""
|
|
||||||
Customized psycopg2.extras.Json to allow for a custom encoder.
|
|
||||||
"""
|
|
||||||
def __init__(self, adapted, dumps=None, encoder=None):
|
|
||||||
self.encoder = encoder
|
|
||||||
super().__init__(adapted, dumps=dumps)
|
|
||||||
|
|
||||||
def dumps(self, obj):
|
|
||||||
options = {'cls': self.encoder} if self.encoder else {}
|
|
||||||
return json.dumps(obj, **options)
|
|
||||||
|
|
||||||
|
|
||||||
class FutureDjangoJSONField(DjangoJSONField):
|
|
||||||
def __init__(self, verbose_name=None, name=None, encoder=None, **kwargs):
|
|
||||||
if encoder and not callable(encoder):
|
|
||||||
raise ValueError("The encoder parameter must be a callable object.")
|
|
||||||
self.encoder = encoder
|
|
||||||
super().__init__(verbose_name, name, **kwargs)
|
|
||||||
|
|
||||||
def deconstruct(self):
|
|
||||||
name, path, args, kwargs = super().deconstruct()
|
|
||||||
if self.encoder is not None:
|
|
||||||
kwargs['encoder'] = self.encoder
|
|
||||||
return name, path, args, kwargs
|
|
||||||
|
|
||||||
def get_prep_value(self, value):
|
|
||||||
if value is not None:
|
|
||||||
return JsonAdapter(value, encoder=self.encoder)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def validate(self, value, model_instance):
|
|
||||||
super().validate(value, model_instance)
|
|
||||||
options = {'cls': self.encoder} if self.encoder else {}
|
|
||||||
try:
|
|
||||||
json.dumps(value, **options)
|
|
||||||
except TypeError:
|
|
||||||
raise exceptions.ValidationError(
|
|
||||||
self.error_messages['invalid'],
|
|
||||||
code='invalid',
|
|
||||||
params={'value': value},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["JSONField"]
|
__all__ = ["JSONField"]
|
||||||
|
|
||||||
class JSONField(FutureDjangoJSONField):
|
|
||||||
|
class JSONField(DjangoJSONField):
|
||||||
def __init__(self, verbose_name=None, name=None, encoder=DjangoJSONEncoder, **kwargs):
|
def __init__(self, verbose_name=None, name=None, encoder=DjangoJSONEncoder, **kwargs):
|
||||||
super().__init__(verbose_name, name, encoder, **kwargs)
|
super().__init__(verbose_name, name, encoder, **kwargs)
|
||||||
|
|
|
@ -252,17 +252,17 @@ def exception_handler(exc):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(exc, APIException):
|
if isinstance(exc, APIException):
|
||||||
headers = {}
|
res = response.Response(format_exception(exc), status=exc.status_code)
|
||||||
if getattr(exc, "auth_header", None):
|
|
||||||
headers["WWW-Authenticate"] = exc.auth_header
|
|
||||||
if getattr(exc, "wait", None):
|
|
||||||
headers["X-Throttle-Wait-Seconds"] = "%d" % exc.wait
|
|
||||||
if getattr(exc, "project_data", None):
|
|
||||||
headers["Taiga-Info-Project-Memberships"] = exc.project_data["total_memberships"]
|
|
||||||
headers["Taiga-Info-Project-Is-Private"] = exc.project_data["is_private"]
|
|
||||||
|
|
||||||
detail = format_exception(exc)
|
if getattr(exc, "auth_header", None):
|
||||||
return response.Response(detail, status=exc.status_code, headers=headers)
|
res["WWW-Authenticate"] = exc.auth_header
|
||||||
|
if getattr(exc, "wait", None):
|
||||||
|
res["X-Throttle-Wait-Seconds"] = "%d" % exc.wait
|
||||||
|
if getattr(exc, "project_data", None):
|
||||||
|
res["Taiga-Info-Project-Memberships"] = exc.project_data["total_memberships"]
|
||||||
|
res["Taiga-Info-Project-Is-Private"] = exc.project_data["is_private"]
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
elif isinstance(exc, Http404):
|
elif isinstance(exc, Http404):
|
||||||
return response.NotFound({'_error_message': str(exc)})
|
return response.NotFound({'_error_message': str(exc)})
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.contrib.contenttypes.management import update_contenttypes
|
from django.contrib.contenttypes.management import create_contenttypes
|
||||||
|
|
||||||
|
|
||||||
def update_all_contenttypes(**kwargs):
|
def update_all_contenttypes(**kwargs):
|
||||||
for app_config in apps.get_app_configs():
|
for app_config in apps.get_app_configs():
|
||||||
update_contenttypes(app_config, **kwargs)
|
create_contenttypes(app_config, **kwargs)
|
||||||
|
|
|
@ -155,7 +155,6 @@ def update_attr_in_bulk_for_ids(values, attr, model):
|
||||||
try:
|
try:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
print("retries", 0)
|
|
||||||
if retries < max_retries:
|
if retries < max_retries:
|
||||||
_run_sql(retries + 1)
|
_run_sql(retries + 1)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.2 on 2017-06-07 23:20
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('external_apps', '0002_remove_application_key'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='application',
|
||||||
|
options={'ordering': ['name', 'id'], 'verbose_name': 'application', 'verbose_name_plural': 'applications'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='applicationtoken',
|
||||||
|
options={'ordering': ['application', 'user'], 'verbose_name': 'application token', 'verbose_name_plural': 'application tolens'},
|
||||||
|
),
|
||||||
|
]
|
|
@ -43,7 +43,7 @@ class Application(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "application"
|
verbose_name = "application"
|
||||||
verbose_name_plural = "applications"
|
verbose_name_plural = "applications"
|
||||||
ordering = ["name"]
|
ordering = ["name", "id"]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -64,6 +64,9 @@ class ApplicationToken(models.Model):
|
||||||
state = models.CharField(max_length=255, null=True, blank=True, default="")
|
state = models.CharField(max_length=255, null=True, blank=True, default="")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
verbose_name = "application token"
|
||||||
|
verbose_name_plural = "application tolens"
|
||||||
|
ordering = ["application", "user",]
|
||||||
unique_together = ("application", "user",)
|
unique_together = ("application", "user",)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -22,7 +22,7 @@ import bleach
|
||||||
|
|
||||||
# BEGIN PATCH
|
# BEGIN PATCH
|
||||||
import html5lib
|
import html5lib
|
||||||
from html5lib.serializer.htmlserializer import HTMLSerializer
|
from html5lib.serializer import HTMLSerializer
|
||||||
|
|
||||||
|
|
||||||
def _serialize(domtree):
|
def _serialize(domtree):
|
||||||
|
|
|
@ -227,7 +227,6 @@ def test_api_create_bulk_members_with_allowed_and_unallowed_domain(client, setti
|
||||||
client.login(project.owner)
|
client.login(project.owner)
|
||||||
response = client.json.post(url, json.dumps(data))
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
print(response.data)
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert "username" in response.data["bulk_memberships"][0]
|
assert "username" in response.data["bulk_memberships"][0]
|
||||||
assert "username" not in response.data["bulk_memberships"][1]
|
assert "username" not in response.data["bulk_memberships"][1]
|
||||||
|
|
Loading…
Reference in New Issue