Source code for beat.web.common.storage

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :

###############################################################################
#                                                                             #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
# Contact: beat.support@idiap.ch                                              #
#                                                                             #
# This file is part of the beat.web module of the BEAT platform.              #
#                                                                             #
# Commercial License Usage                                                    #
# Licensees holding valid commercial BEAT licenses may use this file in       #
# accordance with the terms contained in a written agreement between you      #
# and Idiap. For further information contact tto@idiap.ch                     #
#                                                                             #
# Alternatively, this file may be used under the terms of the GNU Affero      #
# Public License version 3 as published by the Free Software and appearing    #
# in the file LICENSE.AGPL included in the packaging of this file.            #
# The BEAT platform is distributed in the hope that it will be useful, but    #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
#                                                                             #
# You should have received a copy of the GNU Affero Public License along      #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
#                                                                             #
###############################################################################

import os

from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage

# ----------------------------------------------------------


[docs]class OverwriteStorage(FileSystemStorage): def __init__(self, *args, **kwargs): super(OverwriteStorage, self).__init__(*args, **kwargs)
[docs] def get_available_name(self, name, max_length=None): # If the filename already exists, remove it if self.exists(name): self.delete(name) return name
[docs] def delete(self, name): # deletes the file and all the directory structure above super(OverwriteStorage, self).delete(name) def rmdir_recursive(path): if not path or not self.exists(path): return dirs, files = self.listdir(path) if not (dirs or files): os.rmdir(self.path(path)) rmdir_recursive(os.path.dirname(path)) rmdir_recursive(os.path.dirname(name))
# ----------------------------------------------------------
[docs]def get_file_content(instance, attr, binary=False): """Reads the contents of a Django-FileField attribute Parameters: attr (str): The name of the attribute Returns: str: The contents of the file Raises: AttributeError: If the field does not exist """ if hasattr(instance, "_file_contents") and attr in instance._file_contents: return instance._file_contents[attr]["value"] f = getattr(instance, attr) if f is None: return "" mode = "rt" if binary: mode = "rb" try: f.open(mode) except Exception: return "" try: return f.read() finally: f.close() return ""
# ----------------------------------------------------------
[docs]def set_file_content(instance, attr, filename, value): """Provisionally set the content of a Django-FileField attribute The file will be created/overwritten by the save() method. """ if not (hasattr(instance, "_file_contents")): instance._file_contents = {} instance._file_contents[attr] = { "filename": filename, "value": value, }
# ----------------------------------------------------------
[docs]def save_files(instance): """Save the changed files (if necessary)""" if not (hasattr(instance, "_file_contents")): return for attr in instance._file_contents.keys(): current = getattr(instance, attr) if current: current.delete(save=False) newfile = ContentFile(instance._file_contents[attr]["value"]) newfile.name = instance._file_contents[attr]["filename"] setattr(instance, attr, newfile) del instance._file_contents
# ----------------------------------------------------------
[docs]def rename_file(instance, attr, name): current = getattr(instance, attr) if current: current.open() try: value = current.read() finally: current.close() current.delete(save=False) newfile = ContentFile(value) newfile.name = name setattr(instance, attr, newfile) instance.save()