Fix OpenAPI docs, add image import, file preview modal, keyboard nav

- Fix OpenAPI YAML: correct components/schemas indentation (was inside paths:)
- Downgrade openapi version 3.1.0 → 3.0.3 for ReDoc 2.5.2 compatibility
- Add /import/images/<path> endpoint with worker-mode background download
- Add source_url field to FileUpload model (migration 0044)
- Add file preview modal with image/video/audio/unsupported cases
- Add arrow key navigation + prev/next buttons + file counter in modal
- Add /import/images/{image_url} to OpenAPI spec with source_url field

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-03-22 15:11:44 +11:00
co-authored by Copilot
parent 8777aabdc9
commit 64871ab7e0
7 changed files with 346 additions and 3 deletions
+59 -1
View File
@@ -1,4 +1,4 @@
openapi: 3.1.0
openapi: 3.0.3
info:
title: GoLinks API
description: API documentation for GoLinks service
@@ -396,6 +396,56 @@ paths:
description: File content (inline for images, attachment for others)
'404':
description: File not found, is private, or link has expired
/import/images/{image_url}:
get:
summary: Import and cache an external image
description: |
Imports an external image by URL and saves it to the local file store.
The `image_url` path parameter is the image URL **without** the `https://` scheme prefix
(e.g. `example.com/path/to/image.jpg`). The server always tries `https://` first.
**Worker mode** — this endpoint is non-blocking:
- On the **first request** for a given URL the server creates a `FileUpload` record
(marked `is_public: true`) and kicks off a background thread to download and save the file.
The response immediately redirects (HTTP 302) to the original `https://` source URL so the
image is visible right away.
- On **subsequent requests**, once the background download has completed, the response
redirects to the locally-saved public file URL (`/public/files/{uuid}-{filename}`) so the
original host is no longer needed.
**Idempotent** — the same external URL always resolves to the same `FileUpload` record;
the file is only downloaded once.
**Use in Markdown / posts:**
```
![Alt text](http://your-domain/import/images/example.com/path/to/image.jpg)
```
tags:
- Files
parameters:
- in: path
name: image_url
required: true
schema:
type: string
description: |
External image URL without the scheme prefix.
Example: `graziamagazine.com/wp-content/uploads/2024/12/Elle-Fanning-Pigtails-scaled.jpg`
example: graziamagazine.com/wp-content/uploads/2024/12/Elle-Fanning-Pigtails-scaled.jpg
responses:
'302':
description: |
Redirect to either the original source URL (while background download is in progress)
or the locally-saved public file URL (once download has completed).
headers:
Location:
schema:
type: string
description: URL to redirect to (original source or local `/public/files/…`)
components:
schemas:
Page:
type: object
@@ -633,6 +683,14 @@ paths:
download_count:
type: integer
readOnly: true
source_url:
type: string
format: uri
nullable: true
description: |
Original external URL this file was imported from via `/import/images/…`.
`null` for files uploaded directly.
example: https://example.com/path/to/image.jpg
created_at:
type: string
format: date-time