# retoor from __future__ import annotations from ..spec import Action from ._shared import body, confirm, path, query, upload UPLOAD_ACTIONS: tuple[Action, ...] = ( Action( name="upload_file", method="POST", path="/uploads/upload", summary="Upload a local file and obtain its attachment uid", params=(upload("file", "Local filesystem path of the file to upload."),), ), Action( name="list_attachments", method="GET", path="/uploads", summary="List your own uploaded attachments, newest first", description=( "Returns the signed-in user's attachments as {attachments, pagination, total}. Each item " "carries its uid, original_filename, mime_type, url, size, target_type/target_uid/target_url " "(where it is used, if any), and a 'linked' flag. Pass linked=true to list only attachments " "already attached to a post/comment/project/gist/issue, or linked=false for orphaned uploads." ), params=( query("page", "1-based page number, 24 per page."), query("linked", "Filter: true = attached only, false = orphaned only."), ), ), Action( name="get_attachment", method="GET", path="/uploads/{attachment_uid}", summary="Get the metadata of one of your attachments by uid", params=(path("attachment_uid", "Uid of the attachment."),), ), Action( name="rename_attachment", method="PATCH", path="/uploads/{attachment_uid}", summary="Rename an attachment you own (its display filename); the file extension is preserved", description=( "Updates only the display filename of the attachment; the stored file and its extension are " "unchanged (the original extension is always kept, so the file type cannot be altered). " "Administrators may rename any user's attachment." ), params=( path("attachment_uid", "Uid of the attachment."), body("filename", "New display filename.", required=True), ), ), Action( name="attach_url", method="POST", path="/uploads/upload-url", summary="Download a file from a public URL and store it as an attachment, returning its uid", description=( "Fetches the file at the given URL on the server (size-capped, SSRF-guarded) and stores it " "as an attachment exactly like an upload, returning {uid, url, mime_type, ...}. Pass the " "returned uid in attachment_uids when you create_post, create_project, create_gist, " "create_comment, create_issue, or send_message to attach it. The file type is taken from the " "URL or its Content-Type; supply 'filename' (with an allowed extension) when the URL has no " "usable name. Use this to attach an image or file straight from the internet." ), params=( body("url", "Public http(s) URL of the file to download and attach.", required=True), body( "filename", "Optional filename with an allowed extension, used when the URL has no clear name.", ), ), ), Action( name="delete_attachment", method="DELETE", path="/uploads/delete/{attachment_uid}", summary="Delete an uploaded attachment (your own, or anyone's when you are an administrator). Confirmation required", description=( "Removes one attachment by uid. Use list_attachments (or get_attachment) to find the uid of the " "file the user wants gone, then delete it. The attachment leaves the owner's attachment list and " "disappears from every post, comment, project, gist, message, or issue it was attached to, and its " "file stops being served. Only the owner may delete their own; an administrator may delete anyone's " "(otherwise 403); an unknown or already-removed uid returns 404. This is confirmation-gated: the " "first call is refused so you can show the user the exact attachment (filename + where it is used) " "first, and only a repeat call with confirm=true performs it." ), params=(path("attachment_uid", "Uid of the attachment."), confirm()), ), )