Skip to content

Commit

Permalink
Upgrade Django from v3.2 to v4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
tomka committed Dec 4, 2024
1 parent bd319de commit d2a622d
Show file tree
Hide file tree
Showing 19 changed files with 494 additions and 407 deletions.
4 changes: 2 additions & 2 deletions django/applications/catmaid/control/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import _get_queryset, render
from django.template import Context, Template
from django.utils.encoding import force_bytes, force_text
from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.core.mail import EmailMessage

Expand Down Expand Up @@ -892,7 +892,7 @@ def register(request:HttpRequest) -> Union[HttpResponseRedirect, JsonResponse]:

def activate(request:HttpRequest, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
Expand Down
4 changes: 2 additions & 2 deletions django/applications/catmaid/control/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Meta:

class ClientDatastoreList(APIView):
@method_decorator(requires_user_role_for_any_project([UserRole.Browse, UserRole.Annotate]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, format=None) -> Response:
"""List key-value store datastores used by the client.
---
Expand Down Expand Up @@ -96,7 +96,7 @@ class Meta:

class ClientDataList(APIView):
@method_decorator(requires_user_role_for_any_project([UserRole.Browse, UserRole.Annotate]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, name=None, format=None) -> Response:
"""List key-value data in a datastore for the client.
Expand Down
12 changes: 6 additions & 6 deletions django/applications/catmaid/control/deeplink.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class Meta:
class DeepLinkList(APIView):

@method_decorator(requires_user_role([UserRole.Browse]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id) -> Response:
"""List deep-links available to the client.
---
Expand Down Expand Up @@ -227,7 +227,7 @@ def post(self, request:Request, project_id) -> Response:

class DeepLinkSelector(APIView):

@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id, alias) -> Response:
"""Get a deep-links available to the client.
Expand All @@ -242,7 +242,7 @@ def get(self, request:Request, project_id, alias) -> Response:
return HttpResponseRedirect(url)

@method_decorator(requires_user_role_for_any_project([UserRole.Browse]))
@never_cache
@method_decorator(never_cache)
def head(self, request:Request, project_id, alias) -> Response:
"""Get a deep-links available to the client.
---
Expand All @@ -257,7 +257,7 @@ def head(self, request:Request, project_id, alias) -> Response:
return Response('Link not found', status=status.HTTP_404_NOT_FOUND)

@method_decorator(requires_user_role_for_any_project([UserRole.Annotate]))
@never_cache
@method_decorator(never_cache)
def delete(self, request:Request, project_id, alias) -> Response:
"""Delete a deep-links available to the client.
---
Expand All @@ -278,7 +278,7 @@ def delete(self, request:Request, project_id, alias) -> Response:
class DeepLinkDetails(APIView):

@method_decorator(requires_user_role_for_any_project([UserRole.Browse]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id, alias) -> Response:
"""Get details on a deep-link.
---
Expand All @@ -297,7 +297,7 @@ def get(self, request:Request, project_id, alias) -> Response:
class DeepLinkByIdSelector(APIView):

@method_decorator(requires_user_role_for_any_project([UserRole.Annotate]))
@never_cache
@method_decorator(never_cache)
def delete(self, request:Request, project_id, link_id) -> Response:
"""Delete a deep-links available to the client.
---
Expand Down
4 changes: 2 additions & 2 deletions django/applications/catmaid/control/project_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class Meta:
class ProjectTokenList(APIView):

@method_decorator(requires_user_role([UserRole.Admin]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id) -> Response:
"""List project tokens available for this project, if the user is an
admin.
Expand Down Expand Up @@ -130,7 +130,7 @@ def post(self, request:Request, project_id) -> Response:

class UserProjectTokenList(APIView):

@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id) -> JsonResponse:
"""List project tokens available for this project and user.
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Meta:

class SuppressedVirtualTreenodeList(APIView):
@method_decorator(requires_user_role([UserRole.Browse, UserRole.Annotate]))
@never_cache
@method_decorator(never_cache)
def get(self, request:Request, project_id=None, treenode_id=None, format=None) -> Response:
"""List suppressed virtual nodes along the edge to this node.
---
Expand Down
9 changes: 7 additions & 2 deletions django/applications/catmaid/control/synapseclustering.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,13 @@ def distanceMatrix(G, synNodes) -> Tuple[Any, Dict]:
synNodes = set(synNodes)
synIndices = tuple(i for i,node in enumerate(nodeList) if node in synNodes)

dmat = dijkstra(nx.to_scipy_sparse_matrix(G, nodeList),
directed=False, indices=synIndices)
# FIXME: The dtype paratmer and index overrides shouldn't be needed, but the
# Dijkstra implementation fails in SciPy >v1.10 and <v1.15. See PR #20913 in
# SciPy's GitHub repo.
mat = nx.to_scipy_sparse_matrix(G, nodeList, dtype=np.int32)
mat.indices = mat.indices.astype(np.int32)
mat.indptr = mat.indptr.astype(np.int32)
dmat = dijkstra(mat, directed=False, indices=synIndices)

return dmat, {node: i for i,node in enumerate(nodeList)}

Expand Down
2 changes: 1 addition & 1 deletion django/applications/catmaid/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def factory_class(self):
return newclass


composite_type_created = Signal(providing_args=['name'])
composite_type_created = Signal()

# Necessary when running in interactive contexts and from migrations.
@receiver(composite_type_created)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class Command(BaseCommand):
help = 'Set up the required database entries for a project'
requires_system_checks = False
requires_system_checks = []

def add_arguments(self, parser):
parser.add_argument('--project_id', dest='project_id', required=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5052,7 +5052,6 @@ var cola;
return LinkAccessor;
})();
})(cola || (cola = {}));
//# sourceMappingURL=cola.js.map

// patch in conditional cola commonjs support
if( typeof module !== 'undefined' ){
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

28 changes: 27 additions & 1 deletion django/applications/catmaid/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from abc import ABC

from django.db import connection
from django.test import TestCase
from django.test import TestCase, TransactionTestCase
from django.test.client import Client
from catmaid.apps import get_system_user
from catmaid.models import Project
Expand Down Expand Up @@ -84,6 +84,32 @@ def fake_authentication(self):
self.client.login(username='temporary', password='temporary')


class CatmaidTransactionTestCase(TransactionTestCase, AssertStatusMixin):
fixtures = ['catmaid_testdata']

maxDiff = None

@classmethod
def setUpTestData(cls):
init_consistent_data()
# Set up data for the whole TestCase
cls.test_project_id = 3
cls.user = User.objects.create_user('temporary',
'[email protected]', 'temporary')

# Add admin user and test2 users to the test1 group
g = Group.objects.get(name='test1')
g.user_set.add(User.objects.get(username='admin'))
g.user_set.add(User.objects.get(username='test2'))
g.save()

def setUp(self):
self.client = Client()

def fake_authentication(self):
self.client.login(username='temporary', password='temporary')


def round_list(l, digits=6):
"""Round floating point values in a list recursively to the specified number
of digits.
Expand Down
56 changes: 56 additions & 0 deletions django/applications/catmaid/tests/test_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest
from django.test import AsyncClient, TestCase, override_settings
from channels.testing import WebsocketCommunicator
from channels.auth import get_user, login, logout
from channels.db import database_sync_to_async
from catmaid.consumers import UpdateConsumer
from catmaid.models import User
from .common import CatmaidTestCase, CatmaidTransactionTestCase
import functools
from asgiref.sync import sync_to_async


@database_sync_to_async
def get_catmaid_user(username):
try:
return User.objects.get(username=username)
except User.DoesNotExist:
return User.objects.get(username='AnonymousUser')


class AuthWebsocketCommunicator(WebsocketCommunicator):
def __init__(self, application, path, user, *args, **kwargs):
super().__init__(self._asgi_with_user(application, user), path,
*args, **kwargs)

@classmethod
def _asgi_with_user(cls, asgi_app, user):
"""
Update the scope of an ASGI app such that a particular user
is already assumed to have been authenticated.
"""
async def app(scope, receive, send):
scope['user'] = user
return await asgi_app(scope, receive, send)
functools.update_wrapper(app, asgi_app)
return app


@override_settings(CHANNEL_LAYERS={"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}})
class TestWebsockets(CatmaidTransactionTestCase):

async def test_basic_connection(self):
client = AsyncClient()
user = await get_catmaid_user('temporary')

headers = [(b'origin', b'http://localhost:80')] # Bypass AllowedHostsOriginValidator
communicator = AuthWebsocketCommunicator(UpdateConsumer.as_asgi(),
'/channels/updates', user,
headers=headers)

#communicator = WebsocketCommunicator(UpdateConsumer.as_asgi(), "GET", "/channels/updates")
#communicator.instance.scope["user"] = await get_user(username='temporary')
connected, subprotocol = await communicator.connect()
assert connected

await communicator.disconnect()
Loading

0 comments on commit d2a622d

Please sign in to comment.