From 43309bc4479f61a3264a884cda6dbccf73205440 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Fri, 20 Dec 2024 15:03:08 -0800 Subject: [PATCH] WIP - Users CSV export use DefaultStorage --- .../management/commands/bulkexportusers.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/kolibri/core/auth/management/commands/bulkexportusers.py b/kolibri/core/auth/management/commands/bulkexportusers.py index 84735e3407e..08b7a5e41e4 100644 --- a/kolibri/core/auth/management/commands/bulkexportusers.py +++ b/kolibri/core/auth/management/commands/bulkexportusers.py @@ -1,4 +1,5 @@ import csv +import io import logging import ntpath import os @@ -6,6 +7,7 @@ from functools import partial from django.conf import settings +from django.core.files.storage import DefaultStorage from django.core.management.base import CommandError from django.db.models import OuterRef from django.db.models import Subquery @@ -26,7 +28,6 @@ from kolibri.core.query import GroupConcatSubquery from kolibri.core.tasks.management.commands.base import AsyncCommand from kolibri.core.tasks.utils import get_current_job -from kolibri.core.utils.csv import open_csv_for_writing from kolibri.core.utils.csv import output_mapper from kolibri.utils import conf @@ -153,17 +154,20 @@ def translate_labels(): def csv_file_generator(facility, filepath, overwrite=True): - if not overwrite and os.path.exists(filepath): - raise ValueError("{} already exists".format(filepath)) + file_storage = DefaultStorage() + filename = file_storage.generate_filename(filepath.split("/")[-1]) + + if not overwrite and file_storage.exists(filename): + raise ValueError("{} already exists".format(filename)) queryset = FacilityUser.objects.filter(facility=facility) header_labels = translate_labels().values() - csv_file = open_csv_for_writing(filepath) + csv_file = io.BytesIO() with csv_file as f: - writer = csv.DictWriter(f, header_labels) - logger.info("Creating csv file {filename}".format(filename=filepath)) + writer = csv.DictWriter(io.TextIOWrapper(f, encoding="utf-8"), header_labels) + logger.info("Creating users csv file {filename}".format(filename=filepath)) writer.writeheader() usernames = set() @@ -203,6 +207,17 @@ def csv_file_generator(facility, filepath, overwrite=True): usernames.add(item["username"]) yield item + f.seek(0) + file = file_storage.save(filename, f) + + try: + # If the file is local, we can get the path + logger.info("File saved - Path: {}".format(file_storage.path(file))) + except NotImplementedError: + # But if path is not implemented, we assume we can get the URL + logger.info("File saved - Path: {}".format(file_storage.url(file))) + logger.info("File saved - Size: {}".format(file_storage.size(file))) + class Command(AsyncCommand): def add_arguments(self, parser):