ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: filestorage upload и preview вложений

This commit is contained in:
DCCONSTRUCTIONS
2026-04-25 13:05:03 +03:00
parent 5f2d543cab
commit c4032e3040
43 changed files with 982 additions and 127 deletions
@@ -0,0 +1,59 @@
# Copyright (c) 2023-present Plane Software, Inc. and contributors
# SPDX-License-Identifier: AGPL-3.0-only
# See the LICENSE file for details.
from urllib.parse import quote
from botocore.exceptions import ClientError
from django.http import HttpResponse, StreamingHttpResponse
from plane.settings.storage import S3Storage
def attachment_object_exists(asset):
storage = S3Storage(request=None)
try:
storage.s3_client.head_object(
Bucket=storage.aws_storage_bucket_name,
Key=str(asset.asset.name),
)
return True
except ClientError:
return False
def get_attachment_preview_response(request, asset, disposition="inline"):
storage = S3Storage(request=None)
range_header = request.META.get("HTTP_RANGE")
request_kwargs = {
"Bucket": storage.aws_storage_bucket_name,
"Key": str(asset.asset.name),
}
if range_header:
request_kwargs["Range"] = range_header
try:
storage_response = storage.s3_client.get_object(**request_kwargs)
except ClientError:
return HttpResponse("Attachment object not found.", status=404)
content_type = (
asset.attributes.get("type")
or storage_response.get("ContentType")
or "application/octet-stream"
)
filename = quote(asset.attributes.get("name") or "attachment")
response = StreamingHttpResponse(
storage_response["Body"].iter_chunks(chunk_size=8192),
status=206 if storage_response.get("ContentRange") else 200,
content_type=content_type,
)
response["Content-Disposition"] = f"{disposition}; filename*=UTF-8''{filename}"
response["Accept-Ranges"] = "bytes"
if storage_response.get("ContentLength") is not None:
response["Content-Length"] = storage_response["ContentLength"]
if storage_response.get("ContentRange"):
response["Content-Range"] = storage_response["ContentRange"]
return response
@@ -0,0 +1,24 @@
from django.conf import settings
def get_workspace_file_size_limit(workspace):
if not getattr(workspace, "storage_file_size_limit_enabled", True):
return None
limit = getattr(workspace, "storage_file_size_limit", None) or settings.FILE_SIZE_LIMIT
return max(1, int(limit))
def resolve_workspace_upload_size_limit(workspace, requested_size):
try:
requested_size = int(requested_size)
except (TypeError, ValueError):
requested_size = settings.FILE_SIZE_LIMIT
requested_size = max(1, requested_size)
workspace_limit = get_workspace_file_size_limit(workspace)
if workspace_limit is None:
return requested_size
return min(requested_size, workspace_limit)