v1.9.2: S3 right-click context menu — copy presigned download link
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
core/i18n.py
12
core/i18n.py
@@ -390,6 +390,10 @@ _EN = {
|
||||
"s3_uploading_n": "Uploading {count} files...",
|
||||
"s3_uploaded_n": "Uploaded {count} files",
|
||||
"s3_upload_partial": "Uploaded {ok}/{total} files",
|
||||
"s3_copy_link": "Copy Link",
|
||||
"s3_generating_link": "Generating link...",
|
||||
"s3_link_copied": "Link copied to clipboard",
|
||||
"s3_link_failed": "Failed to generate link",
|
||||
|
||||
# Grafana tab
|
||||
"grafana_refresh": "Refresh",
|
||||
@@ -892,6 +896,10 @@ _RU = {
|
||||
"s3_uploading_n": "Загрузка {count} файлов...",
|
||||
"s3_uploaded_n": "Загружено {count} файлов",
|
||||
"s3_upload_partial": "Загружено {ok}/{total} файлов",
|
||||
"s3_copy_link": "Копировать ссылку",
|
||||
"s3_generating_link": "Генерация ссылки...",
|
||||
"s3_link_copied": "Ссылка скопирована",
|
||||
"s3_link_failed": "Ошибка генерации ссылки",
|
||||
|
||||
# Grafana tab
|
||||
"grafana_refresh": "Обновить",
|
||||
@@ -1394,6 +1402,10 @@ _ZH = {
|
||||
"s3_uploading_n": "正在上传 {count} 个文件...",
|
||||
"s3_uploaded_n": "已上传 {count} 个文件",
|
||||
"s3_upload_partial": "已上传 {ok}/{total} 个文件",
|
||||
"s3_copy_link": "复制链接",
|
||||
"s3_generating_link": "生成链接中...",
|
||||
"s3_link_copied": "链接已复制",
|
||||
"s3_link_failed": "生成链接失败",
|
||||
|
||||
# Grafana tab
|
||||
"grafana_refresh": "刷新",
|
||||
|
||||
@@ -277,6 +277,26 @@ class S3Client:
|
||||
log.error("S3 delete failed: %s", exc)
|
||||
return False
|
||||
|
||||
def generate_presigned_url(self, bucket: str, key: str,
|
||||
expires_in: int = 3600) -> str | None:
|
||||
"""Generate a presigned download URL for an object.
|
||||
|
||||
expires_in: URL lifetime in seconds (default 1 hour).
|
||||
Returns URL string or None on failure.
|
||||
"""
|
||||
if not self._ensure_connected():
|
||||
return None
|
||||
try:
|
||||
url = self._client.generate_presigned_url(
|
||||
"get_object",
|
||||
Params={"Bucket": bucket, "Key": key},
|
||||
ExpiresIn=expires_in,
|
||||
)
|
||||
return url
|
||||
except Exception as exc:
|
||||
log.error("S3 presigned URL failed: %s", exc)
|
||||
return None
|
||||
|
||||
def get_object_size(self, bucket: str, key: str) -> int:
|
||||
"""Get size of an object in bytes."""
|
||||
if not self._ensure_connected():
|
||||
|
||||
Reference in New Issue
Block a user