django-storages icon indicating copy to clipboard operation
django-storages copied to clipboard

Add ability to get object/file attributes with listdir variant

Open johnbyrne7 opened this issue 3 years ago • 0 comments

I sometimes want to get the attributes (size, modtime) for my S3 and local filesystem objects when using listdir. I could not see how to do that, so I created custom storage classes like this. Can this capability be added to the base implementations?

class CustomS3Boto3Storage(S3Boto3Storage): def listdirAttributes(self, name): path = self._normalize_name(self._clean_name(name)) # The path needs to end with a slash, but if the root is empty, leave it. if path and not path.endswith('/'): path += '/'

	directories = []
	files = []
	paginator = self.connection.meta.client.get_paginator('list_objects')
	pages = paginator.paginate(Bucket=self.bucket_name, Delimiter='/', Prefix=path)
	for page in pages:
		for entry in page.get('CommonPrefixes', ()):
			directories.append(posixpath.relpath(entry['Prefix'], path))
		for entry in page.get('Contents', ()):
			key = entry['Key']
			if key != path:
				attrs = {}
				attrs['name'] = posixpath.relpath(key, path)
				attrs['size'] = entry['Size']
				attrs['modified'] = str(entry['LastModified'])
				files.append(attrs)
	return directories, files

class CustomFileSystemStorage(FileSystemStorage):

def listdirAttributes(self, path):
	path = self.path(path)
	dtz = timezone.get_default_timezone()
	directories, files = [], []

	for entry in os.listdir(path):
		if os.path.isdir(os.path.join(path, entry)):
			directories.append(entry)
		else:
			attrs = {}
			attrs['name'] = entry
			file = os.stat(os.path.join(path, entry))
			attrs['size'] = file.st_size
			attrs['modified'] = str(datetime.fromtimestamp(file.st_mtime, dtz))
			files.append(attrs)
	return directories, files

johnbyrne7 avatar Nov 11 '21 14:11 johnbyrne7