Esempio n. 1
0
def field_file_to_local_path(
        field_file: FieldFile) -> Generator[Path, None, None]:
    """
    Provide a filesystem path to the content of a FieldFile.

    Normally, a FieldFile is usable as a Python file-like object, as:
    `with model.field.open() as file_stream:`

    However, in some use cases, particularly when invoking third-party libraries,
    an actual filesystem path to the content is required. This context manager
    provides this as:
    `with field_file_to_local_path(model.field) as file_path:`

    When this context manager exists, the filesystem content and path will be
    garbage collected.
    """
    with field_file.open('rb'):
        file_obj: File = field_file.file

        if type(file_obj) is File:
            # When file_obj is an actual File, (typically backed by FileSystemStorage),
            # it is already at a stable path on disk.
            yield Path(file_obj.name)
        else:
            # When file_obj is actually a subclass of File, it only provides a Python
            # file-like object API. So, it must be copied to a stable path.
            field_file_basename = PurePath(field_file.name).name
            with tempfile.NamedTemporaryFile(
                    'wb', suffix=field_file_basename) as dest_stream:
                shutil.copyfileobj(file_obj, dest_stream)
                dest_stream.flush()

                yield Path(dest_stream.name)
Esempio n. 2
0
def get_exif(file_: FieldFile) -> str:
    """
    Use exiftool to extract exif data from the given file field.
    """
    exiftool_path = shutil.which('exiftool')
    if not exiftool_path:
        raise ExifError('Could not find `exiftool`')

    if not file_._committed:
        # pipe file content to exiftool
        fo = file_._file
        fo.seek(0)
    else:
        fo = file_.open()

    process = subprocess.run(
        [exiftool_path, '-j', '-l', '-'],
        check=True,
        input=fo.read(),
        stdout=subprocess.PIPE,
    )
    return process.stdout
Esempio n. 3
0
def compute_checksum_file(field_file: FieldFile, chunk_num_blocks=128):
    with field_file.open() as f:
        return _compute_hash(f, chunk_num_blocks)