Skip to content

Commit

Permalink
Feature/286 (#330)
Browse files Browse the repository at this point in the history
* #294 fix: Update experiment update conditions

* fix: Fix registration of fiducial experiments

* feat: Move populations to error state if cordmap doesn't produce cell files

* fix: Rollback custom cordmap changes

* #294 fix: Improve update experiment logic

* #286 feat: Change csv headers at download time

* fix: Update population cells file location
  • Loading branch information
afonsobspinto authored Nov 17, 2023
1 parent 3e65a2d commit 76c44a1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
48 changes: 48 additions & 0 deletions applications/portal/backend/api/helpers/download_populations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import csv
import io
import os
import tempfile
import zipfile

from django.db.models import Q
from django.http import HttpResponse

from api.models import Population


def get_populations_zip(active_populations, experiment):
filename_prefix = f'{experiment.name}' if experiment else 'population'
filename_suffix = 's' if len(active_populations) > 1 else ''

temp_file = tempfile.TemporaryFile()
with zipfile.ZipFile(temp_file, 'w') as zip_file:
for population in Population.objects.filter(Q(experiment=experiment) | Q(experiment=None), id__in=active_populations):
if population.cells:
modified_csv_content = modify_csv_headers(population.cells.path)
zip_file.writestr(os.path.basename(population.cells.path), modified_csv_content)
filename_prefix += f"_{population.name}"

temp_file.seek(0) # Reset file pointer
return temp_file, f"{filename_prefix}_population{filename_suffix}.zip"



def modify_csv_headers(csv_file_path):
with open(csv_file_path, 'r') as csvfile:
reader = csv.reader(csvfile)
modified_data = io.StringIO()
writer = csv.writer(modified_data)

# Swap 'x' and 'y' in headers
headers = next(reader)
x_index = headers.index('x')
y_index = headers.index('y')
headers[x_index], headers[y_index] = headers[y_index], headers[x_index]
writer.writerow(headers)

# Write the rest of the rows as they are
for row in reader:
writer.writerow(row)

modified_data.seek(0)
return modified_data.getvalue()
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def associate_population_cells_file(population, storage_path, csv_suffix):
new_file_name = f"{csv_suffix}_{str(uuid.uuid4())[:8]}.csv"
new_file_path = move_file(
original_file_path,
os.path.join(population.storage_path, str(population.id)),
population.storage_path,
new_file_name
)
with open(new_file_path, 'rb') as file:
Expand Down
32 changes: 9 additions & 23 deletions applications/portal/backend/api/views/rest/experiment.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import logging
import os
import tempfile
import zipfile

from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from dry_rest_permissions.generics import DRYPermissions
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

from api.helpers.download_populations import get_populations_zip
from api.helpers.exceptions import InvalidPopulationFile, DuplicatedPopulationError, InvalidInputError
from api.models import Experiment, Population
from api.models import Experiment
from api.serializers import (
ExperimentPairFileUploadSerializer,
ExperimentSerializer,
Expand Down Expand Up @@ -68,7 +65,7 @@ def destroy(self, request, *args, **kwargs):
pk = kwargs.get("pk")
queryset = self.get_queryset()
instance = get_object_or_404(queryset, pk=pk)
if request.user==instance.owner:
if request.user == instance.owner:
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=status.HTTP_403_FORBIDDEN)
Expand Down Expand Up @@ -190,22 +187,11 @@ def download_populations(self, request, pk=None, active_populations=None):
if not active_populations or len(active_populations) == 0:
return Response(status=status.HTTP_204_NO_CONTENT)

filename_prefix = f'{experiment.name}' if experiment else 'population'
filename_suffix = 's' if len(active_populations) > 1 else ''
with tempfile.TemporaryFile() as temp_file:
with zipfile.ZipFile(temp_file, 'w') as zip_file:
for population in Population.objects.filter(Q(experiment=experiment) | Q(experiment=None),
id__in=active_populations):
if population.cells:
zip_file.write(population.cells.path, arcname=os.path.basename(population.cells.path))
filename_prefix += f"_{population.name}"

temp_file.seek(0) # move the file pointer to the beginning of the file

response = HttpResponse(temp_file.read(), content_type='application/octet-stream')
response[
'Content-Disposition'] = f'attachment; filename="{filename_prefix}_population{filename_suffix}.zip"'
return response
zip_file, filename = get_populations_zip(active_populations, experiment)
response = HttpResponse(zip_file.read(), content_type='application/octet-stream')
response['Content-Disposition'] = f'attachment; filename="{filename}"'
zip_file.close()
return response

def perform_create(self, serializer):
experiment = serializer.save(owner=self.request.user)

0 comments on commit 76c44a1

Please sign in to comment.