pasteup 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pasteup-0.1.0 → pasteup-0.2.0}/CHANGELOG.md +27 -1
- {pasteup-0.1.0 → pasteup-0.2.0}/PKG-INFO +214 -25
- {pasteup-0.1.0 → pasteup-0.2.0}/README.md +213 -24
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/__init__.py +1 -1
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/models/schemas.py +96 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/routes/jobs.py +142 -1
- pasteup-0.2.0/src/pasteup/services/folder_browser.py +152 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/folder_scanner.py +37 -4
- pasteup-0.2.0/src/pasteup/services/upscaler.py +152 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/css/styles.css +249 -5
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/js/app.js +431 -34
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/templates/index.html +67 -2
- pasteup-0.2.0/tests/test_browse_folder_api.py +165 -0
- pasteup-0.2.0/tests/test_macos_metadata_files.py +127 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_request_safety.py +1 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_ui_generation_modes.py +61 -3
- pasteup-0.2.0/tests/test_upscale_images.py +249 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/.github/workflows/release.yml +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/.github/workflows/tests.yml +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/.gitignore +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/LICENSE +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/SECURITY.md +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/pyproject.toml +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/scripts/protect-repo.sh +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/__main__.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/cli.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/main.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/models/__init__.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/routes/__init__.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/routes/ui.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/__init__.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/cover_collage.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/exporter.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/grid_composer.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/image_batcher.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/services/video_exporter.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/shortcut.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/favicon.svg +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/fonts/OFL-Caveat.txt +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/fonts/OFL-PatrickHand.txt +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/fonts/caveat-latin-700.woff2 +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/src/pasteup/static/fonts/patrick-hand-latin-400.woff2 +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/conftest.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_batch_cover_collage_api.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_cli.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_cover_collage.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_cover_collage_api.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_generate_all_folders.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_generate_single_folder_video_status.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_grid_composer.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_image_batcher.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_page_dpi_and_geometry.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_partial_page_and_generation_options.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_scan_folder_api.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_scan_selected_batch_folders.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_transparent_png_handling.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_ui_defaults.py +0 -0
- {pasteup-0.1.0 → pasteup-0.2.0}/tests/test_video_exporter.py +0 -0
|
@@ -7,6 +7,31 @@ All notable changes to Pasteup are recorded here. The format follows
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-10-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Browse…** beside the folder field opens a folder browser, so a folder can be
|
|
14
|
+
picked instead of typed. It opens at the folder in the field, or at your home
|
|
15
|
+
folder, says how many images the folder you're in holds, and scans the one
|
|
16
|
+
you choose. Typing or pasting a path still works.
|
|
17
|
+
(`POST /api/jobs/browse-folder`)
|
|
18
|
+
- Upscaled images, from a tile of their own in step 3: every image of a bundle,
|
|
19
|
+
or of each picked bundle, made 2x, 3x or 4x bigger and saved in an
|
|
20
|
+
`Upscaled` folder as a PNG, which keeps any transparency, and a JPG on
|
|
21
|
+
white. (`POST /api/jobs/upscale-images`, `POST /api/jobs/upscale-images-batch`)
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Hidden files are no longer counted as images. A Mac writes a hidden `._`
|
|
25
|
+
file beside the files it copies to an exFAT or FAT32 drive or to some network
|
|
26
|
+
shares, so such a bundle could scan as twice its size, and making sheets then
|
|
27
|
+
reported the extra files as unreadable.
|
|
28
|
+
- Hidden folders, such as the `.Spotlight-V100` and `.Trashes` a Mac keeps on
|
|
29
|
+
those drives, and the `__MACOSX` folder left by unpacking a zip made on a
|
|
30
|
+
Mac, are no longer offered as bundles. Covers no longer take images from
|
|
31
|
+
them, nor from a `---Created---` folder inside the bundle.
|
|
32
|
+
- After a scan or making images, keyboard focus returns to the button that
|
|
33
|
+
started it, instead of falling back to the top of the page.
|
|
34
|
+
|
|
10
35
|
## [0.1.0] - 2026-10-16
|
|
11
36
|
|
|
12
37
|
The first release on PyPI.
|
|
@@ -29,5 +54,6 @@ The first release on PyPI.
|
|
|
29
54
|
already running and moves to a free port when another program has 8000.
|
|
30
55
|
`pasteup --shortcut` makes a double-click launcher.
|
|
31
56
|
|
|
32
|
-
[Unreleased]: https://github.com/ftymoshchuk/pasteup/compare/v0.
|
|
57
|
+
[Unreleased]: https://github.com/ftymoshchuk/pasteup/compare/v0.2.0...HEAD
|
|
58
|
+
[0.2.0]: https://github.com/ftymoshchuk/pasteup/compare/v0.1.0...v0.2.0
|
|
33
59
|
[0.1.0]: https://github.com/ftymoshchuk/pasteup/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pasteup
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Turn a folder of clip art into listing images: preview sheets, cover collages and preview videos.
|
|
5
5
|
Project-URL: Source, https://github.com/ftymoshchuk/pasteup
|
|
6
6
|
Project-URL: Issues, https://github.com/ftymoshchuk/pasteup/issues
|
|
@@ -50,6 +50,8 @@ publishing: cut out by hand and pasted onto a layout board.
|
|
|
50
50
|
main image.
|
|
51
51
|
- **Preview video:** an MP4 slideshow of the sheets, exactly as long as you ask
|
|
52
52
|
(Etsy's listing videos run 5 to 15 s).
|
|
53
|
+
- **Upscaled images:** every image made 2x, 3x or 4x bigger, saved in an
|
|
54
|
+
`Upscaled` folder as a PNG, which keeps any transparency, and a JPG on white.
|
|
53
55
|
- **Clean-up:** transparent PNGs land on white instead of black, phone photos
|
|
54
56
|
are turned upright, and near-white backgrounds can be removed.
|
|
55
57
|
- **Batch mode:** process every bundle folder under a parent folder in one go.
|
|
@@ -73,6 +75,21 @@ it without installing anything: `uvx pasteup`.
|
|
|
73
75
|
For changes not released yet, install from GitHub instead:
|
|
74
76
|
`pipx install git+https://github.com/ftymoshchuk/pasteup.git`.
|
|
75
77
|
|
|
78
|
+
### No pipx yet?
|
|
79
|
+
Install pipx once (or uv, which needs nothing else), then open a new terminal
|
|
80
|
+
window so the command is found:
|
|
81
|
+
|
|
82
|
+
- **macOS:** `brew install pipx`, then `pipx ensurepath`. Without
|
|
83
|
+
[Homebrew](https://brew.sh), install uv instead:
|
|
84
|
+
`curl -LsSf https://astral.sh/uv/install.sh | sh`
|
|
85
|
+
- **Windows:** `py -m pip install --user pipx`, then `py -m pipx ensurepath`.
|
|
86
|
+
Or install uv from PowerShell:
|
|
87
|
+
`powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`
|
|
88
|
+
- **Linux:** `sudo apt install pipx` (Debian, Ubuntu) or `sudo dnf install pipx`
|
|
89
|
+
(Fedora), then `pipx ensurepath`.
|
|
90
|
+
|
|
91
|
+
Then run `pipx install pasteup`, or `uv tool install pasteup` if you chose uv.
|
|
92
|
+
|
|
76
93
|
## Run
|
|
77
94
|
```bash
|
|
78
95
|
pasteup
|
|
@@ -135,7 +152,8 @@ PyPI trusts `release.yml` running in this repository's `pypi` environment.
|
|
|
135
152
|
Project layout:
|
|
136
153
|
- `src/pasteup/main.py`: the FastAPI app
|
|
137
154
|
- `src/pasteup/routes/`: the page and the `/api/jobs` endpoints
|
|
138
|
-
- `src/pasteup/services/`: scanning, page composition,
|
|
155
|
+
- `src/pasteup/services/`: scanning and browsing folders, page composition,
|
|
156
|
+
collages, export, video
|
|
139
157
|
- `src/pasteup/models/`: request and response schemas
|
|
140
158
|
- `src/pasteup/templates/` and `src/pasteup/static/`: the UI
|
|
141
159
|
- `src/pasteup/cli.py`: the `pasteup` command; `shortcut.py` makes its launchers
|
|
@@ -152,6 +170,12 @@ Input scan supports the following image extensions (case-insensitive):
|
|
|
152
170
|
|
|
153
171
|
Notes:
|
|
154
172
|
- Folder scan is **non-recursive** (only files directly inside the selected folder).
|
|
173
|
+
- Hidden files, whose names start with a dot, are skipped. Most are the `._`
|
|
174
|
+
files a Mac writes beside the files it copies to an exFAT or FAT32 drive or
|
|
175
|
+
to some network shares: they carry the image's extension but hold no image.
|
|
176
|
+
- Hidden folders, `__MACOSX` (left by unpacking a zip made on a Mac) and
|
|
177
|
+
`---Created---` are never offered as bundles, and covers don't look inside
|
|
178
|
+
them.
|
|
155
179
|
- Export output format supports `PNG` and `JPG`.
|
|
156
180
|
|
|
157
181
|
---
|
|
@@ -170,12 +194,15 @@ Default UI values:
|
|
|
170
194
|
- `background_tolerance`: `240`
|
|
171
195
|
- `background_feather`: `1`
|
|
172
196
|
- `include_partial_page`: `false`
|
|
197
|
+
- upscaling `scale`: `2` (also `3` or `4`)
|
|
173
198
|
|
|
174
199
|
Behavior defaults:
|
|
175
200
|
- Scan sample size: first `5` files (`sample_files`) in sorted order.
|
|
176
201
|
- Images per page: `12` (fixed 4x3).
|
|
177
202
|
- Export naming: `page_001`, `page_002`, ...
|
|
178
203
|
- Export conflict handling: never overwrite existing `page_###`; continue at next index.
|
|
204
|
+
- Upscaled images keep their image's name, in `Upscaled/PNG` and `Upscaled/JPG`,
|
|
205
|
+
so upscaling again replaces the files the last run made.
|
|
179
206
|
|
|
180
207
|
---
|
|
181
208
|
|
|
@@ -187,7 +214,7 @@ Health check endpoint.
|
|
|
187
214
|
|
|
188
215
|
**Response**
|
|
189
216
|
```json
|
|
190
|
-
{"status": "ok", "app": "pasteup", "version": "0.
|
|
217
|
+
{"status": "ok", "app": "pasteup", "version": "0.2.0"}
|
|
191
218
|
```
|
|
192
219
|
|
|
193
220
|
### `POST /api/jobs/scan-folder`
|
|
@@ -205,8 +232,40 @@ Validates a folder and scans for supported image files.
|
|
|
205
232
|
- `image_count` (int): number of supported files found.
|
|
206
233
|
- `sample_files` (list[str]): up to 5 sorted sample filenames.
|
|
207
234
|
- `estimated_pages` (int): `image_count // 12` (whole pages only).
|
|
235
|
+
- `available_subfolders` (list): when the folder has no images of its own, the
|
|
236
|
+
folders inside it, each with `display_name` and `full_path`, for picking one
|
|
237
|
+
bundle or listing many. Hidden folders, `__MACOSX` and `---Created---` are
|
|
238
|
+
left out. Empty when the folder has images.
|
|
208
239
|
- `message` (str): summary or error detail.
|
|
209
240
|
|
|
241
|
+
### `POST /api/jobs/browse-folder`
|
|
242
|
+
Lists the folders inside a folder, for the folder browser behind **Browse…**. A
|
|
243
|
+
page can't read the path of a folder picked with the browser's own file
|
|
244
|
+
chooser, so the UI browses through this instead.
|
|
245
|
+
|
|
246
|
+
**Request body**
|
|
247
|
+
```json
|
|
248
|
+
{
|
|
249
|
+
"folder_path": "~/Pictures"
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
A blank `folder_path` lists the home folder.
|
|
253
|
+
|
|
254
|
+
**Response fields**
|
|
255
|
+
- `path` (str): the folder listed. One that does not exist or cannot be opened
|
|
256
|
+
gives way to the nearest folder above it that can, and `message` says why.
|
|
257
|
+
- `parent_path` (str | null): the folder above it; `null` at the top of a drive.
|
|
258
|
+
- `breadcrumbs` (list): `name` and `path` of each folder from the top of the
|
|
259
|
+
drive down to this one.
|
|
260
|
+
- `folders` (list): `name` and `path` of each folder inside, sorted, leaving
|
|
261
|
+
out hidden folders, `__MACOSX` and `---Created---`.
|
|
262
|
+
- `image_count` (int): supported images directly inside, counted as
|
|
263
|
+
`scan-folder` counts them.
|
|
264
|
+
- `places` (list): shortcuts: the home folder, its Desktop, Documents,
|
|
265
|
+
Downloads and Pictures folders when it has them, and each drive on Windows.
|
|
266
|
+
- `message` (str): empty unless a different folder was listed than the one
|
|
267
|
+
asked for.
|
|
268
|
+
|
|
210
269
|
### `POST /api/jobs/scan-selected-batch-folders`
|
|
211
270
|
Validates selected batch subfolders under a scanned parent folder and reports which selected folders are ready for generation.
|
|
212
271
|
|
|
@@ -292,6 +351,7 @@ and the response message gives ffmpeg's error.
|
|
|
292
351
|
- `output_files` (list[str]): generated file paths
|
|
293
352
|
- `output_path` (str): normalized output folder path
|
|
294
353
|
- `images_dropped` (int): trailing images left out because they did not fill a page
|
|
354
|
+
- `images_skipped` (int): files that could not be read as images
|
|
295
355
|
- `backgrounds_cleaned` (int): images whose background was cleaned
|
|
296
356
|
- `page_geometry` (str): resolved page size, e.g. `3000x2400px (10.00x8.00in at 300 DPI)`
|
|
297
357
|
- `video_file` (str | null), `video_created` (bool): the preview video, when requested
|
|
@@ -324,13 +384,139 @@ Used by the UI in **Many bundles** mode. Iterates bundle folders under a parent
|
|
|
324
384
|
- `bundle_results` (list): per-folder generation summaries
|
|
325
385
|
- `message` (str): batch generation summary
|
|
326
386
|
|
|
387
|
+
### `POST /api/jobs/generate-cover-collage`
|
|
388
|
+
Makes one cover image for a folder: its images arranged in one of three layouts.
|
|
389
|
+
|
|
390
|
+
**Request body**
|
|
391
|
+
```json
|
|
392
|
+
{
|
|
393
|
+
"folder_path": "/path/to/images",
|
|
394
|
+
"output_path": "/path/to/output",
|
|
395
|
+
"page_width": 3000,
|
|
396
|
+
"page_height": 3000,
|
|
397
|
+
"format": "JPG",
|
|
398
|
+
"collage_template": "randomized-grid",
|
|
399
|
+
"selected_cover_images": ["cover001.jpg", "cover002.png"]
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
- `collage_template` (`randomized-grid` | `feature-spread` | `center-stage`,
|
|
403
|
+
default `randomized-grid`): the layout.
|
|
404
|
+
- `image_fit` (`cover` | `contain`, default `cover`): `cover` fills each tile
|
|
405
|
+
and crops the overflow; `contain` fits the whole image and leaves margins.
|
|
406
|
+
- `selected_cover_images` (list of file names, optional): use only these files.
|
|
407
|
+
Names must match exactly, extension included; when none of them match, the
|
|
408
|
+
request fails and says so.
|
|
409
|
+
- The output quality fields above apply too.
|
|
410
|
+
|
|
411
|
+
**Response fields**
|
|
412
|
+
- `success` (bool)
|
|
413
|
+
- `total_images` (int): images in the collage
|
|
414
|
+
- `pages_generated` (int)
|
|
415
|
+
- `output_files` (list[str]): the cover's file path
|
|
416
|
+
- `output_path` (str)
|
|
417
|
+
- `page_geometry` (str): resolved page size
|
|
418
|
+
- `message` (str)
|
|
419
|
+
|
|
420
|
+
### `POST /api/jobs/generate-cover-collage-batch`
|
|
421
|
+
Makes one cover per bundle folder, as `/generate-all-folders` does for sheets.
|
|
422
|
+
|
|
423
|
+
**Request body**
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"parent_folder_path": "/path/to/parent-folder",
|
|
427
|
+
"created_output_root_path": "/path/to/created-output-root",
|
|
428
|
+
"selected_subfolders": ["/path/to/parent-folder/bundle-a", "/path/to/parent-folder/bundle-b"],
|
|
429
|
+
"page_width": 3000,
|
|
430
|
+
"page_height": 3000,
|
|
431
|
+
"format": "JPG",
|
|
432
|
+
"collage_template": "feature-spread"
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
`collage_template`, `image_fit` and the output quality fields work as for
|
|
436
|
+
`/generate-cover-collage`.
|
|
437
|
+
|
|
438
|
+
**Response fields**
|
|
439
|
+
- `success` (bool)
|
|
440
|
+
- `created_output_root_path` (str)
|
|
441
|
+
- `processed_folders`, `selected_folders`, `total_detected_folders`,
|
|
442
|
+
`generated_folders` (int): as for `/generate-all-folders`
|
|
443
|
+
- `bundle_results` (list): per bundle, `folder_name`, `success`,
|
|
444
|
+
`pages_generated`, `total_images`, `output_path`, `output_files` and `message`
|
|
445
|
+
- `message` (str)
|
|
446
|
+
|
|
447
|
+
### `POST /api/jobs/upscale-images`
|
|
448
|
+
Makes every image of a folder bigger, saving each as a PNG and as a JPG in an
|
|
449
|
+
`Upscaled` folder inside `output_path`: `Upscaled/PNG/<name>.png` and
|
|
450
|
+
`Upscaled/JPG/<name>.jpg`. The PNG keeps any transparency; the JPG is
|
|
451
|
+
flattened onto white. Images are resampled with Lanczos, which keeps edges
|
|
452
|
+
smooth but adds no detail.
|
|
453
|
+
|
|
454
|
+
**Request body**
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"folder_path": "/path/to/images",
|
|
458
|
+
"output_path": "/path/to/output",
|
|
459
|
+
"scale": 2,
|
|
460
|
+
"dpi": 300
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
- `scale` (`2` | `3` | `4`, default `2`): how many times bigger each side becomes.
|
|
464
|
+
- `dpi` (int, 1-1200, default `300`): stamped into every file.
|
|
465
|
+
- Each file keeps its image's name, so upscaling again replaces what the last
|
|
466
|
+
run made.
|
|
467
|
+
- Files sharing a name in different formats, such as `art.png` and `art.jpg`,
|
|
468
|
+
would be saved over each other, so one gives both formats: PNG first, then
|
|
469
|
+
WebP, then JPG.
|
|
470
|
+
- Upscaled images are capped at 100 megapixels; an image that would pass that
|
|
471
|
+
is left out and named in the response.
|
|
472
|
+
|
|
473
|
+
**Response fields**
|
|
474
|
+
- `success` (bool): whether any image was upscaled
|
|
475
|
+
- `scale` (int)
|
|
476
|
+
- `total_images` (int): images upscaled
|
|
477
|
+
- `output_path` (str): the `Upscaled` folder
|
|
478
|
+
- `png_folder`, `jpg_folder` (str): the two folders inside it
|
|
479
|
+
- `output_files` (list[str]): every file written
|
|
480
|
+
- `images_skipped` (int): files that could not be read as images
|
|
481
|
+
- `too_large_files` (list[str]): images left out for passing the cap
|
|
482
|
+
- `same_name_files` (list[str]): files left out for sharing a name with the
|
|
483
|
+
image that was used
|
|
484
|
+
- `message` (str)
|
|
485
|
+
|
|
486
|
+
### `POST /api/jobs/upscale-images-batch`
|
|
487
|
+
Upscales each selected bundle into `<created_output_root_path>/<bundle>/Upscaled`.
|
|
488
|
+
|
|
489
|
+
**Request body**
|
|
490
|
+
```json
|
|
491
|
+
{
|
|
492
|
+
"parent_folder_path": "/path/to/parent-folder",
|
|
493
|
+
"created_output_root_path": "/path/to/created-output-root",
|
|
494
|
+
"selected_subfolders": ["/path/to/parent-folder/bundle-a", "/path/to/parent-folder/bundle-b"],
|
|
495
|
+
"scale": 4,
|
|
496
|
+
"dpi": 300
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Response fields**
|
|
501
|
+
- `success` (bool)
|
|
502
|
+
- `created_output_root_path` (str)
|
|
503
|
+
- `processed_folders`, `selected_folders`, `total_detected_folders`,
|
|
504
|
+
`generated_folders` (int): as for `/generate-all-folders`
|
|
505
|
+
- `scale` (int)
|
|
506
|
+
- `bundle_results` (list): per bundle, `folder_name`, `success`,
|
|
507
|
+
`total_images`, `output_path`, `images_skipped`, `too_large_files`,
|
|
508
|
+
`same_name_files` and `message`
|
|
509
|
+
- `message` (str)
|
|
510
|
+
|
|
327
511
|
---
|
|
328
512
|
|
|
329
513
|
## Using the app
|
|
330
|
-
1. Run `pasteup
|
|
514
|
+
1. Run `pasteup`; it opens in your browser.
|
|
331
515
|
2. **Pick your clip art.** Choose **One bundle** (a folder of images) or **Many
|
|
332
|
-
bundles** (a folder with one folder inside per bundle),
|
|
333
|
-
|
|
516
|
+
bundles** (a folder with one folder inside per bundle), then click
|
|
517
|
+
**Browse…**: open folders until you're in the right one, and **Use this
|
|
518
|
+
folder** scans it. Or type or paste its path and click **Scan folder**.
|
|
519
|
+
Results go in a `---Created---` folder next to it.
|
|
334
520
|
- One bundle: **Folder check** says how many images it found and how many
|
|
335
521
|
full sheets of 12 they make. If the folder holds only other folders, pick
|
|
336
522
|
one under **Choose folders**.
|
|
@@ -338,8 +524,8 @@ Used by the UI in **Many bundles** mode. Iterates bundle folders under a parent
|
|
|
338
524
|
Untick any you want to skip. A bundle that fails its check can be unticked,
|
|
339
525
|
or fixed and checked again with **Check selected bundles**.
|
|
340
526
|
3. **Set up the page.** Size, units, DPI and format apply to sheets and covers
|
|
341
|
-
alike. **Clean up white backgrounds** can
|
|
342
|
-
white or transparent.
|
|
527
|
+
alike, and DPI to upscaled images too. **Clean up white backgrounds** can
|
|
528
|
+
make near-white backgrounds pure white or transparent.
|
|
343
529
|
4. **Make your images.**
|
|
344
530
|
- **Preview sheets:** every image, 12 to a page (`POST /api/jobs/generate`,
|
|
345
531
|
or `POST /api/jobs/generate-all-folders` for many bundles), optionally with a
|
|
@@ -348,6 +534,10 @@ Used by the UI in **Many bundles** mode. Iterates bundle folders under a parent
|
|
|
348
534
|
(`POST /api/jobs/generate-cover-collage`, or
|
|
349
535
|
`POST /api/jobs/generate-cover-collage-batch`). **Only use certain images**
|
|
350
536
|
limits it to the files you name.
|
|
537
|
+
- **Upscaled images:** every image 2x, 3x or 4x bigger, as a PNG and a JPG
|
|
538
|
+
in an `Upscaled` folder (`POST /api/jobs/upscale-images`, or
|
|
539
|
+
`POST /api/jobs/upscale-images-batch`). It runs on its own, with no
|
|
540
|
+
sheets or cover needed.
|
|
351
541
|
5. **Your files** lists what was made and where it was saved; **Copy** puts a
|
|
352
542
|
path on the clipboard.
|
|
353
543
|
|
|
@@ -360,27 +550,20 @@ Used by the UI in **Many bundles** mode. Iterates bundle folders under a parent
|
|
|
360
550
|
- Trailing images that do not fill a complete page are left out by default; the
|
|
361
551
|
response reports how many. Set `include_partial_page: true` to render that final
|
|
362
552
|
page with its unused cells left white.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
## Acceptance Checklist (MVP Scope)
|
|
367
|
-
- [ ] App runs locally with FastAPI and serves UI.
|
|
368
|
-
- [ ] Folder scan validates path and reports supported image count.
|
|
369
|
-
- [ ] Supported file types: JPG/JPEG/PNG/WEBP.
|
|
370
|
-
- [ ] Estimated pages computed using fixed 12 images/page.
|
|
371
|
-
- [ ] Generation creates fixed 4x3 grids with centered, aspect-preserving fit.
|
|
372
|
-
- [ ] Transparent PNGs composite onto white rather than black.
|
|
373
|
-
- [ ] Exports carry DPI metadata so the page has a real physical size.
|
|
374
|
-
- [ ] Background cleaning only touches near-white areas connected to the border.
|
|
375
|
-
- [ ] Output exports as PNG or JPG.
|
|
376
|
-
- [ ] Exports use sequential naming (`page_###`) and avoid overwriting existing files.
|
|
377
|
-
- [ ] API returns clear success/error messages for scan and generation.
|
|
378
|
-
- [ ] UI supports end-to-end flow: input paths → scan → generate.
|
|
553
|
+
- Upscaling resamples each image: edges stay smooth, but no detail is added,
|
|
554
|
+
so at 4x clip art looks soft. AI upscalers can invent detail; Pasteup has
|
|
555
|
+
none built in.
|
|
379
556
|
|
|
380
557
|
---
|
|
381
558
|
|
|
382
559
|
## Troubleshooting
|
|
383
560
|
|
|
561
|
+
### `pasteup` runs an old version
|
|
562
|
+
An earlier `pip install` of Pasteup can come first on your PATH. List every
|
|
563
|
+
copy with `type -a pasteup` (macOS, Linux) or `where pasteup` (Windows), and
|
|
564
|
+
remove the old one with `pip uninstall pasteup` in the environment it belongs
|
|
565
|
+
to. `pasteup --version` then shows the version pipx or uv installed.
|
|
566
|
+
|
|
384
567
|
### Transparent PNGs used to come out with a black background
|
|
385
568
|
Fixed. Transparent areas are composited onto the page's white rather than having
|
|
386
569
|
the alpha channel dropped, which is what left `(0, 0, 0)` showing through. This
|
|
@@ -440,7 +623,7 @@ Symptoms:
|
|
|
440
623
|
Fixes:
|
|
441
624
|
- Confirm files are directly in the selected folder (non-recursive scan).
|
|
442
625
|
- Confirm extensions are supported.
|
|
443
|
-
- Check
|
|
626
|
+
- Check the files aren't hidden: names starting with a dot are skipped.
|
|
444
627
|
|
|
445
628
|
### Permission errors
|
|
446
629
|
Symptoms:
|
|
@@ -452,6 +635,12 @@ Fixes:
|
|
|
452
635
|
- Verify write permission on output folder.
|
|
453
636
|
- Try a user-owned directory (for example inside your home directory).
|
|
454
637
|
|
|
638
|
+
### "Pasteup isn't allowed to open" Desktop, Documents or Downloads on a Mac
|
|
639
|
+
macOS asks before a program reads these folders, and Pasteup reads them as the
|
|
640
|
+
terminal app it runs in (Terminal, for the `pasteup --shortcut` launcher). If
|
|
641
|
+
that was refused, turn the folder on for your terminal app under **System
|
|
642
|
+
Settings › Privacy & Security › Files and Folders**, then restart Pasteup.
|
|
643
|
+
|
|
455
644
|
---
|
|
456
645
|
|
|
457
646
|
## How images are loaded
|