One sourceless object image per object + on-device image download (ADR 0018)#502
Open
brickbots wants to merge 1 commit into
Open
One sourceless object image per object + on-device image download (ADR 0018)#502brickbots wants to merge 1 commit into
brickbots wants to merge 1 commit into
Conversation
…nload ADR 0018: store and display exactly one survey JPEG per object, named without a survey suffix (<digit>/<image_name>.jpg). Survey provenance becomes a recorded-but-not-runtime-branched curation directive in object_images.source. - New shared core object_image_store.py: on-disk/CDN layout, sourceless resolve_image_name, worklist_for_scope (All/catalog/filter/list) and 404-tolerant download_object_image. Collapses path logic that was duplicated across cat_images / get_images / gen_images. - cat_images: sourceless resolution; get_display_image drops the source concept (orientation/overlay logic unchanged, ADR 0003). - object_details: remove the dead DM_SDSS display mode (never assigned). - object_images gains a nullable source TEXT column (schema + committed DB via ALTER); the importer leaves it NULL (uncurated). gen_images reads it (NULL->POSS) and publishes one sourceless image per object. - On-device Download feature: app-owned ObjectImageDownloader (background worker thread + controller), a Tools > Download Images scope picker (All / Current Filter / Observing List), a preflight (WiFi-client gate, missing count + size estimate + CDN reachability), a progress screen, and a global title-bar status line shown while a download runs. - get_images: rewritten as a thin CLI over the core (All/single-catalog). Retire audit_images.py (dev-only, hardcoded path). - v2.7.0 migration renames legacy _POSS/_SDSS files to the sourceless name (POSS wins when both exist); idempotent and version-gated. - Tests for the core, the controller and the migration; user docs updated for the on-device flow. New UI strings are wrapped in _(); .po extraction is deferred to the project's controlled release-time babel pass (per repo i18n practice). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Two coupled changes, fully designed in ADR 0018 and the Catalog glossary (
docs/ax/catalog/CONTEXT.md→ Object images):M31_POSS.jpg,M31_SDSS.jpg) to one sourceless image per object (<digit>/<image_name>.jpg). The runtime only ever displayed POSS (DM_SDSSwas defined but never assigned), so the second file was pure cost. Survey provenance becomes a recorded-but-not-runtime-branched curation directive inobject_images.source.python -m PiFinder.get_imagesstep.Highlights
Shared core —
object_image_store.pyCentralizes the on-disk/CDN layout, sourceless
resolve_image_name(with the common-name fallback that maps e.g. M 31 → its canonicalNGC224image),worklist_for_scope(All / single-catalog via DB; filter / observing-list via live objects →object_id→ canonicalimage_name), and a 404-tolerantdownload_object_image. Collapses path logic that was duplicated acrosscat_images,get_imagesandgen_images.Runtime
cat_images.get_display_imagedrops thesourceconcept; orientation/overlay logic (ADR 0003) untouched.object_details: deadDM_SDSSdisplay mode removed.Data
object_imagesgains a nullablesource TEXTcolumn (schema + committedpifinder_objects.dbviaALTER— all rows NULL = uncurated, the intended initial state; no on-device DB migration). The importer leaves it NULL;gen_imagesreads it (NULL→POSS) and publishes one sourceless image per object.On-device Download
ObjectImageDownloader(background worker thread + start/cancel/progress controller, created inmain.py, survives screen navigation).Tools ▸ Download Imagesscope picker → All Objects / Current Filter / Observing List.CLI & migration
get_images.pyrewritten as a thin CLI over the core (All /--catalog NGC).audit_images.pyretired.migration_source/v2.7.0.sh+migrations/v2_7_0_sourceless_images.py: rename legacy_POSS/_SDSS→ sourceless (POSS wins when both exist); stdlib-only, idempotent, version-gated bypifinder_post_update.sh.Decisions / deviations (flagged)
screen_update()that does not reflow each screen's content, drawn only while a download is active._(). Running full babel here produces an unscoped mega-diff (the committed.pofiles are already missing many prior features' strings), so extraction is left to the project's controlled release-time pass, consistent with current practice.docs/.../Image_download_001.pngis reused as a placeholder and should be refreshed to the new screen.Validation
ruff check✅,ruff format --check✅,mypy PiFinder✅ (no issues, 140 files).test_ui_modulessweep (259) — which constructs & exercises the new screen for all scopes — passes; smoke+unit suite (717) passes.🤖 Generated with Claude Code