starbash 0.3.3__tar.gz → 0.3.5__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.
Files changed (129) hide show
  1. {starbash-0.3.3 → starbash-0.3.5}/PKG-INFO +43 -39
  2. {starbash-0.3.3 → starbash-0.3.5}/README.md +40 -37
  3. {starbash-0.3.3 → starbash-0.3.5}/pyproject.toml +14 -4
  4. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/app.py +48 -5
  5. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/repo.py +19 -4
  6. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/database.py +86 -10
  7. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/doit.py +10 -10
  8. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/exception.py +1 -1
  9. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/os.py +1 -1
  10. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/processed_target.py +21 -2
  11. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/publish/github.py +145 -5
  12. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/publish/github_service.py +5 -1
  13. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/target.md.jinja +20 -5
  14. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/base.py +17 -1
  15. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/graxpert.py +2 -1
  16. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/rcastro.py +8 -2
  17. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/siril.py +8 -3
  18. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/starnet.py +17 -2
  19. starbash-0.3.5/src/starbash/ui/qt/launcher.py +32 -0
  20. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/main_window.py +3 -0
  21. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/processing.py +24 -0
  22. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/repositories.py +2 -2
  23. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/wizard.py +38 -20
  24. {starbash-0.3.3 → starbash-0.3.5}/LICENSE +0 -0
  25. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/__init__.py +0 -0
  26. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/aliases.py +0 -0
  27. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/analytics.py +0 -0
  28. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/__init__.py +0 -0
  29. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/check.png +0 -0
  30. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/favicon.ico +0 -0
  31. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/icon.png +0 -0
  32. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/icon.svg +0 -0
  33. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/assets/starbash.desktop.in +0 -0
  34. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/check_version.py +0 -0
  35. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/__init__.py +0 -0
  36. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/gui.py +0 -0
  37. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/info.py +0 -0
  38. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/process.py +0 -0
  39. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/publish.py +0 -0
  40. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/select.py +0 -0
  41. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/commands/user.py +0 -0
  42. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/defaults/__init__.py +0 -0
  43. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/defaults/starbash.toml +0 -0
  44. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/doit_types.py +0 -0
  45. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/dwarf3.py +0 -0
  46. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/events.py +0 -0
  47. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/filtering.py +0 -0
  48. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/fits.py +0 -0
  49. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/interaction.py +0 -0
  50. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/linux.py +0 -0
  51. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/main.py +0 -0
  52. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/parameters.py +0 -0
  53. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/paths.py +0 -0
  54. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/preferences.py +0 -0
  55. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/processing.py +0 -0
  56. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/processing_like.py +0 -0
  57. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/publish/__init__.py +0 -0
  58. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/publish/credentials.py +0 -0
  59. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/publish/github_publish.py +0 -0
  60. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/recipes/README.md +0 -0
  61. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/recipes/__init__.py +0 -0
  62. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/recipes/crop.py +0 -0
  63. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/recipes/osc.py +0 -0
  64. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/recipes/report_registration.py +0 -0
  65. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/report.py +0 -0
  66. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/rich.py +0 -0
  67. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/run_state.py +0 -0
  68. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/safety.py +0 -0
  69. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/score.py +0 -0
  70. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/selection.py +0 -0
  71. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/sim_siril/__init__.py +0 -0
  72. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/sim_siril/connection.py +0 -0
  73. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/sim_siril/enums.py +0 -0
  74. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/sim_siril/utility.py +0 -0
  75. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/siril/import_registration.py +0 -0
  76. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/stage_utils.py +0 -0
  77. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/stages.py +0 -0
  78. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/__init__.py +0 -0
  79. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/repo/master.toml +0 -0
  80. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/repo/processed.toml +0 -0
  81. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/Gemfile +0 -0
  82. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/README.md.jinja +0 -0
  83. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/__init__.py +0 -0
  84. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/_config.yml +0 -0
  85. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/default.html +0 -0
  86. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/report/index.md.jinja +0 -0
  87. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/target/master.toml +0 -0
  88. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/target/processed/about.toml +0 -0
  89. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/target/processed/main.toml +0 -0
  90. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/target/processed/sessions.toml +0 -0
  91. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/templates/userconfig.toml +0 -0
  92. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/toml.py +0 -0
  93. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/__init__.py +0 -0
  94. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/context.py +0 -0
  95. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/tool/python.py +0 -0
  96. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/__init__.py +0 -0
  97. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/cli.py +0 -0
  98. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/cli_events.py +0 -0
  99. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/__init__.py +0 -0
  100. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/app.py +0 -0
  101. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/bridge.py +0 -0
  102. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/desktop.py +0 -0
  103. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/interaction.py +0 -0
  104. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/jobs.py +0 -0
  105. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/models.py +0 -0
  106. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/__init__.py +0 -0
  107. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/base.py +0 -0
  108. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/dashboard.py +0 -0
  109. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/masters.py +0 -0
  110. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/publish.py +0 -0
  111. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/sessions.py +0 -0
  112. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/settings.py +0 -0
  113. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/pages/targets.py +0 -0
  114. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/services.py +0 -0
  115. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/theme.py +0 -0
  116. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/__init__.py +0 -0
  117. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/busy_indicator.py +0 -0
  118. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/file_links.py +0 -0
  119. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/github_login.py +0 -0
  120. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/hover_preview.py +0 -0
  121. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/image_viewer.py +0 -0
  122. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/log_view.py +0 -0
  123. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/master_picker.py +0 -0
  124. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/selection_panel.py +0 -0
  125. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/stat_card.py +0 -0
  126. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/widgets/tool_warning.py +0 -0
  127. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/ui/qt/workers.py +0 -0
  128. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/url.py +0 -0
  129. {starbash-0.3.3 → starbash-0.3.5}/src/starbash/windows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: starbash
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: A tool for automating/standardizing/sharing astrophotography workflows.
5
5
  License-File: LICENSE
6
6
  Author: Kevin Hester
@@ -12,10 +12,10 @@ Classifier: Programming Language :: Python :: 3.13
12
12
  Classifier: Programming Language :: Python :: 3.14
13
13
  Requires-Dist: astropy (>=7.1.1)
14
14
  Requires-Dist: doit (>=0.36.0)
15
- Requires-Dist: graxpert[cpuonly] (>=3.2.0a2,<4.0.0)
15
+ Requires-Dist: graxpert[cpuonly] (>=3.2.0a3,<4.0.0)
16
16
  Requires-Dist: jinja2 (>=3.1,<4.0)
17
17
  Requires-Dist: keyring (>=25.6)
18
- Requires-Dist: numpy (==2.2.6)
18
+ Requires-Dist: numpy (>=2.2.6)
19
19
  Requires-Dist: platformdirs (>=4.5.0,<5.0.0)
20
20
  Requires-Dist: pygal (>=3.0,<4.0)
21
21
  Requires-Dist: pyqt6 (>=6.10.1,<7.0.0)
@@ -79,7 +79,12 @@ This project is still very young - but making good progress 😊!
79
79
 
80
80
  If you are interested in alpha-testing we ❤️ you. This README should have enough instructions to get you going, but if you encounter **any** problems please file a github issue and we'll work together to fix them.
81
81
 
82
- ![Sample session movie](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/doc/vhs/sample-session.gif)
82
+ (new!) We now have a full GUI (click the video to play)...
83
+
84
+ <video src="https://github.com/user-attachments/assets/0791c47f-f8fa-4279-be06-f869d7212d8c" autoplay controls loop muted playsinline width="100%"></video>
85
+
86
+ We have a CLI interface also...
87
+ ![CLI sample session](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/doc/vhs/sample-session.gif)
83
88
 
84
89
  ## Current features
85
90
 
@@ -108,6 +113,7 @@ If you are interested in alpha-testing we ❤️ you. This README should have e
108
113
 
109
114
  ## Features coming soon
110
115
 
116
+ * Fixed SHO/HOO auto post processing pipeline for dual narrowband OSC filters. Currently everything after pallete recomposition looks bad for those workflows (prior stage outputs are all good though)
111
117
  * Recipe 'writers guide' documentation. Currently iterating based on usage reports 😄
112
118
  * Support for mono-camera workflows (this alpha only includes osc recipes).
113
119
  * The target report can be used to auto-generate a human-friendly 'postable/shareable' report about that image.
@@ -147,7 +153,37 @@ Completion will take effect once you restart the terminal
147
153
 
148
154
  ```
149
155
 
150
- ## Use
156
+ ## Supported telescope software
157
+
158
+ * N.I.N.A. - tested, seems fairly okay.
159
+ * Asiair - tested, seems fairly okay.
160
+ * Seestar - tested, seems fairly okay.
161
+ * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
162
+ * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
163
+
164
+ ## Supported tools (now)
165
+ Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
166
+
167
+ * [Siril](https://siril.org/)
168
+ * [Graxpert](https://graxpert.com/) - for background and noise elimination
169
+ * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
170
+ * [starnet](https://starnetastro.com/cli-tools/) - for star removal
171
+ * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
172
+
173
+ ## Desktop GUI
174
+
175
+ Prefer clicking to typing? Starbash ships a desktop app that
176
+ covers the same ground as the CLI — browse sessions and preview frames, edit the
177
+ selection, run the pipeline and watch every stage live, tweak per-target stage
178
+ exclusions, manage repositories, and build the report site.
179
+
180
+ ```bash
181
+ sb
182
+ ```
183
+
184
+ ## CLI
185
+
186
+ ** Warning: The following instructions are written wrt to the CLI. The newer GUI can do all the same things - but easier/prettier. So most users should use the GUI first **
151
187
 
152
188
  ### Initial setup
153
189
 
@@ -224,22 +260,6 @@ sb publish github # Publish to github
224
260
  See the [GitHub publishing guide](doc/publish/github.md) for prerequisites,
225
261
  preview instructions, authentication, and troubleshooting.
226
262
 
227
- ### Desktop GUI
228
-
229
- Prefer clicking to typing? Starbash ships a desktop app (built on PySide6) that
230
- covers the same ground as the CLI — browse sessions and preview frames, edit the
231
- selection, run the pipeline and watch every stage live, tweak per-target stage
232
- exclusions, manage repositories, and build the report site.
233
-
234
- ```bash
235
- sb gui
236
- ```
237
-
238
- PySide6 is installed with Starbash, so there is nothing extra to add. The GUI is
239
- optional in the sense that you can ignore it completely and keep driving Starbash
240
- from the command line: both front ends share the same selection, config and
241
- database, so you can mix them freely.
242
-
243
263
  ## Supported commands
244
264
 
245
265
  ### Repository Management
@@ -275,23 +295,6 @@ database, so you can mix them freely.
275
295
  - `sb process auto [SESSIONNUM]` - Automatic processing. If session # is specified, process only that session; otherwise all selected sessions will be processed.
276
296
  - `sb process masters` - Generate master flats, darks, and biases from available raw frames in the current selection.
277
297
 
278
- ## Supported telescope software
279
-
280
- * N.I.N.A. - tested, seems fairly okay.
281
- * Asiair - tested, seems fairly okay.
282
- * Seestar - tested, seems fairly okay.
283
- * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
284
- * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
285
-
286
- ## Supported tools (now)
287
- Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
288
-
289
- * [Siril](https://siril.org/)
290
- * [Graxpert](https://graxpert.com/) - for background and noise elimination
291
- * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
292
- * [starnet](https://starnetastro.com/cli-tools/) - for star removal
293
- * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
294
-
295
298
  ## Credits
296
299
  * Various reddit users who submitted anonymous crash reports from alpha 1
297
300
  * [@codegistics](https://github.com/codegistics) for kindly donating Dwarf3 test data and invaluable debugging assistance.
@@ -319,5 +322,6 @@ However, in some of my other open-source projects, I've seen the current hell PR
319
322
 
320
323
  ## License
321
324
 
322
- Copyright 2025 Kevin Hester, kevinh@geeksville.com.
325
+ Copyright 2025, 2026 Kevin Hester, kevinh@geeksville.com.
323
326
  Licensed under the [GPL v3](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/LICENSE)
327
+
@@ -46,7 +46,12 @@ This project is still very young - but making good progress 😊!
46
46
 
47
47
  If you are interested in alpha-testing we ❤️ you. This README should have enough instructions to get you going, but if you encounter **any** problems please file a github issue and we'll work together to fix them.
48
48
 
49
- ![Sample session movie](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/doc/vhs/sample-session.gif)
49
+ (new!) We now have a full GUI (click the video to play)...
50
+
51
+ <video src="https://github.com/user-attachments/assets/0791c47f-f8fa-4279-be06-f869d7212d8c" autoplay controls loop muted playsinline width="100%"></video>
52
+
53
+ We have a CLI interface also...
54
+ ![CLI sample session](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/doc/vhs/sample-session.gif)
50
55
 
51
56
  ## Current features
52
57
 
@@ -75,6 +80,7 @@ If you are interested in alpha-testing we ❤️ you. This README should have e
75
80
 
76
81
  ## Features coming soon
77
82
 
83
+ * Fixed SHO/HOO auto post processing pipeline for dual narrowband OSC filters. Currently everything after pallete recomposition looks bad for those workflows (prior stage outputs are all good though)
78
84
  * Recipe 'writers guide' documentation. Currently iterating based on usage reports 😄
79
85
  * Support for mono-camera workflows (this alpha only includes osc recipes).
80
86
  * The target report can be used to auto-generate a human-friendly 'postable/shareable' report about that image.
@@ -114,7 +120,37 @@ Completion will take effect once you restart the terminal
114
120
 
115
121
  ```
116
122
 
117
- ## Use
123
+ ## Supported telescope software
124
+
125
+ * N.I.N.A. - tested, seems fairly okay.
126
+ * Asiair - tested, seems fairly okay.
127
+ * Seestar - tested, seems fairly okay.
128
+ * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
129
+ * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
130
+
131
+ ## Supported tools (now)
132
+ Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
133
+
134
+ * [Siril](https://siril.org/)
135
+ * [Graxpert](https://graxpert.com/) - for background and noise elimination
136
+ * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
137
+ * [starnet](https://starnetastro.com/cli-tools/) - for star removal
138
+ * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
139
+
140
+ ## Desktop GUI
141
+
142
+ Prefer clicking to typing? Starbash ships a desktop app that
143
+ covers the same ground as the CLI — browse sessions and preview frames, edit the
144
+ selection, run the pipeline and watch every stage live, tweak per-target stage
145
+ exclusions, manage repositories, and build the report site.
146
+
147
+ ```bash
148
+ sb
149
+ ```
150
+
151
+ ## CLI
152
+
153
+ ** Warning: The following instructions are written wrt to the CLI. The newer GUI can do all the same things - but easier/prettier. So most users should use the GUI first **
118
154
 
119
155
  ### Initial setup
120
156
 
@@ -191,22 +227,6 @@ sb publish github # Publish to github
191
227
  See the [GitHub publishing guide](doc/publish/github.md) for prerequisites,
192
228
  preview instructions, authentication, and troubleshooting.
193
229
 
194
- ### Desktop GUI
195
-
196
- Prefer clicking to typing? Starbash ships a desktop app (built on PySide6) that
197
- covers the same ground as the CLI — browse sessions and preview frames, edit the
198
- selection, run the pipeline and watch every stage live, tweak per-target stage
199
- exclusions, manage repositories, and build the report site.
200
-
201
- ```bash
202
- sb gui
203
- ```
204
-
205
- PySide6 is installed with Starbash, so there is nothing extra to add. The GUI is
206
- optional in the sense that you can ignore it completely and keep driving Starbash
207
- from the command line: both front ends share the same selection, config and
208
- database, so you can mix them freely.
209
-
210
230
  ## Supported commands
211
231
 
212
232
  ### Repository Management
@@ -242,23 +262,6 @@ database, so you can mix them freely.
242
262
  - `sb process auto [SESSIONNUM]` - Automatic processing. If session # is specified, process only that session; otherwise all selected sessions will be processed.
243
263
  - `sb process masters` - Generate master flats, darks, and biases from available raw frames in the current selection.
244
264
 
245
- ## Supported telescope software
246
-
247
- * N.I.N.A. - tested, seems fairly okay.
248
- * Asiair - tested, seems fairly okay.
249
- * Seestar - tested, seems fairly okay.
250
- * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
251
- * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
252
-
253
- ## Supported tools (now)
254
- Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
255
-
256
- * [Siril](https://siril.org/)
257
- * [Graxpert](https://graxpert.com/) - for background and noise elimination
258
- * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
259
- * [starnet](https://starnetastro.com/cli-tools/) - for star removal
260
- * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
261
-
262
265
  ## Credits
263
266
  * Various reddit users who submitted anonymous crash reports from alpha 1
264
267
  * [@codegistics](https://github.com/codegistics) for kindly donating Dwarf3 test data and invaluable debugging assistance.
@@ -286,5 +289,5 @@ However, in some of my other open-source projects, I've seen the current hell PR
286
289
 
287
290
  ## License
288
291
 
289
- Copyright 2025 Kevin Hester, kevinh@geeksville.com.
290
- Licensed under the [GPL v3](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/LICENSE)
292
+ Copyright 2025, 2026 Kevin Hester, kevinh@geeksville.com.
293
+ Licensed under the [GPL v3](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/LICENSE)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "starbash"
3
- version = "0.3.3"
3
+ version = "0.3.5"
4
4
  description = "A tool for automating/standardizing/sharing astrophotography workflows."
5
5
  authors = ["Kevin Hester <kevinh@geeksville.com>"]
6
6
  readme = "README.md"
@@ -32,13 +32,13 @@ toml-repo = "^0.1.7"
32
32
 
33
33
  # Note: to use graxpert from the local tree rather than pypi use:
34
34
  # graxpert = {path = "GraXpert", extras = ["cpuonly"], develop = true}
35
- graxpert = {version = "^3.2.0a2", extras = ["cpuonly"]}
35
+ graxpert = {version = "^3.2.0a3", extras = ["cpuonly"]}
36
36
 
37
37
  # The following two libs are only needed for the (temporary) experiment of running siril scripts directly...
38
38
  # experimenting with siril-scripts/processing/VeraLux_HyperMetric_Stretch.py
39
39
  # pyqt6 is used *only* by those out-of-process siril scripts; Starbash itself never imports it,
40
40
  # so it can safely coexist with PySide6 (which the GUI *does* import).
41
- numpy = "2.2.6"
41
+ numpy = ">=2.2.6"
42
42
  pyqt6 = "^6.10.1"
43
43
  # The desktop GUI (`sb gui`) binding. A normal dependency: the GUI is a first-class
44
44
  # way to drive Starbash. "Optional" only means users may keep using the CLI instead.
@@ -61,6 +61,10 @@ doit-graph = ">=0.3.0"
61
61
  # harlequin = "^2.4.1"
62
62
  library-skills = "^0.0.19"
63
63
  semble = {version = "^0.6.0", extras = ["mcp"]}
64
+ imageio-ffmpeg = "^0.6.0"
65
+
66
+ [tool.poetry.group.packaging.dependencies]
67
+ pyinstaller = ">=6.17.0,<7.0.0"
64
68
 
65
69
  [tool.poetry.scripts]
66
70
  starbash = "starbash.main:app"
@@ -71,6 +75,7 @@ markers = [
71
75
  "slow: marks tests as slow (deselect with '-m \"not slow\"')",
72
76
  "integration: marks tests as integration tests requiring /test-data (deselect with '-m \"not integration\"')",
73
77
  "gui: marks tests that build real Qt widgets (offscreen; deselect with '-m \"not gui\"')",
78
+ "gui_integration: marks the scripted gui_integration movie runs (needs ffmpeg + /test-data; deselect with '-m \"not gui_integration\"')",
74
79
  ]
75
80
  # -n auto enables parallel test execution plugin
76
81
  # By default we exclude only slow and integration tests. GUI tests DO run: PySide6
@@ -80,7 +85,12 @@ markers = [
80
85
  # --tb=short shows shorter tracebacks
81
86
  # -rfE shows summary of failed and error test outcomes at end (not passed)
82
87
  # --ignore excludes third-party test directories
83
- addopts = "-m 'not slow and not integration' -n auto --tb=short -rfE --ignore=GraXpert --ignore=starbash-recipes"
88
+ addopts = "-m 'not slow and not integration and not gui_integration' -n auto --tb=short -rfE --ignore=GraXpert --ignore=starbash-recipes"
89
+
90
+ # Note: the `gui_integration` movies are deselected by default on purpose: they drive a
91
+ # whole user journey (setup wizard -> reindex -> processing run) and take minutes, so they
92
+ # run on demand - `just test-integration-gui`, or `pytest -m gui_integration -n 0`.
93
+ # The marker name uses an underscore so it is usable as `pytest.mark.gui_integration`.
84
94
 
85
95
  # Note: To limit captured output further, you can:
86
96
  # 1. Use --tb=line for minimal tracebacks
@@ -34,6 +34,7 @@ from starbash.check_version import check_version
34
34
  from starbash.database import (
35
35
  Database,
36
36
  ImageRow,
37
+ RepoRemoval,
37
38
  SearchCondition,
38
39
  SessionRow,
39
40
  get_column_name,
@@ -691,13 +692,21 @@ class Starbash:
691
692
  """
692
693
  return self._find_user_repo_ref(url) is not None
693
694
 
694
- def remove_repo_ref(self, url: str) -> None:
695
+ def remove_repo_ref(self, url: str) -> RepoRemoval:
695
696
  """
696
697
  Remove a repository reference from the user configuration.
697
698
 
699
+ Also drops everything the repository contributed to the index: its image
700
+ rows, and the sessions those images built. A session never spans
701
+ repositories, so all of its frames go with the repo and there is nothing
702
+ left for it to describe.
703
+
698
704
  Args:
699
705
  url: The repository URL to remove (e.g., 'file:///path/to/repo')
700
706
 
707
+ Returns:
708
+ A :class:`~starbash.database.RepoRemoval` describing what was dropped.
709
+
701
710
  Raises:
702
711
  UserHandledError: If the repository URL is not found in user configuration
703
712
  """
@@ -708,12 +717,21 @@ class Starbash:
708
717
  # indexed rows would only force a pointless re-index later.
709
718
  raise UserHandledError(f"Repository '{url}' not found in user configuration.")
710
719
 
711
- self.db.remove_repo(url)
720
+ removal = self.db.remove_repo(url)
712
721
  self.user_repo.config.get("repo-ref", []).remove(ref)
713
722
 
723
+ # Drop it from the in-memory manager too: everything that lists repos
724
+ # (``sb repo list``, the GUI's Repositories page) reads it, so without
725
+ # this the removed repository keeps showing until the app is restarted.
726
+ repo = self.repo_manager.get_repo_by_url(url)
727
+ if repo is not None:
728
+ self.repo_manager.repos.remove(repo)
729
+
714
730
  # Write the updated config
715
731
  self.user_repo.write_config()
716
732
 
733
+ return removal
734
+
717
735
  def _extend_image_header(self, headers: dict[str, Any], full_image_path: Path) -> bool:
718
736
  """Given a FITS header dictionary, possibly extend it with additional computed fields.
719
737
  Returns True if the header is invalid and should be skipped."""
@@ -810,7 +828,9 @@ class Starbash:
810
828
  # (otherwise invariants will get messed up)
811
829
  self._add_session(headers)
812
830
 
813
- def reindex_repo(self, repo: Repo, subdir: str | None = None) -> None:
831
+ def reindex_repo(
832
+ self, repo: Repo, subdir: str | None = None, clean: bool = False
833
+ ) -> RepoRemoval:
814
834
  """Scan one repo's files into the database.
815
835
 
816
836
  Progress is *reported*, never drawn: the scan publishes
@@ -825,17 +845,30 @@ class Starbash:
825
845
  Args:
826
846
  repo: the repo to scan.
827
847
  subdir: scan only this subdirectory of the repo (for debugging).
848
+ clean: drop the repo's indexed images and sessions before scanning, so
849
+ every frame counts as a first scan and its session is (re)built.
850
+
851
+ Returns:
852
+ What ``clean`` dropped from the index -- empty when not cleaning.
828
853
  """
829
854
 
830
855
  # make sure this new repo is listed in the repos table
831
856
  self.repo_db_update() # not really ideal, a more optimal version would just add the new repo
832
857
 
858
+ dropped = RepoRemoval()
833
859
  path = repo.get_path()
834
860
 
835
861
  repo_kind = repo.kind()
836
862
  if path and repo.is_scheme("file") and repo_kind != "recipe":
837
863
  logging.debug("Reindexing %s...", repo.url)
838
864
 
865
+ if clean:
866
+ # Wiping the repo's rows first is what makes the scan below a
867
+ # *full* re-read: it skips any frame already indexed, and only
868
+ # builds a session for one it meets for the first time.
869
+ dropped = self.db.reset_repo(repo.url)
870
+ logging.debug("Cleared the index for %s: %s", repo.url, dropped.summary())
871
+
839
872
  if subdir:
840
873
  path = path / subdir
841
874
  # used to debug
@@ -876,15 +909,25 @@ class Starbash:
876
909
  {"repo": repo.url, "indexed": total_files},
877
910
  )
878
911
 
879
- def reindex_repos(self) -> None:
912
+ return dropped
913
+
914
+ def reindex_repos(self, clean: bool = False) -> RepoRemoval:
880
915
  """Reindex all repositories managed by the RepoManager.
881
916
 
882
917
  Reports progress through the event bus only -- see :meth:`reindex_repo`.
918
+
919
+ Args:
920
+ clean: drop each repo's indexed images and sessions before scanning it.
921
+
922
+ Returns:
923
+ What ``clean`` dropped from the index across all repos.
883
924
  """
884
925
  logging.debug("Reindexing all repositories...")
885
926
 
927
+ dropped = RepoRemoval()
886
928
  for repo in self.repo_manager.repos:
887
- self.reindex_repo(repo)
929
+ dropped += self.reindex_repo(repo, clean=clean)
930
+ return dropped
888
931
 
889
932
  def get_recipes(self) -> list[Repo]:
890
933
  """Get all recipe repos available, sorted by priority (lower number first).
@@ -9,6 +9,7 @@ from toml_repo import Repo
9
9
  import starbash
10
10
  from starbash import console
11
11
  from starbash.app import Starbash
12
+ from starbash.database import RepoRemoval
12
13
  from starbash.paths import get_user_documents_dir
13
14
  from starbash.ui.cli import ReindexView
14
15
 
@@ -175,9 +176,12 @@ def remove(
175
176
  raise typer.Exit(code=1)
176
177
  repo_url = repo_to_remove.url
177
178
 
178
- # Remove the repo reference from user config
179
- sb.remove_repo_ref(repo_url)
179
+ # Remove the repo reference from user config. That also drops everything
180
+ # the repo contributed to the index: its frames, and the sessions those
181
+ # frames built.
182
+ removal = sb.remove_repo_ref(repo_url)
180
183
  console.print(f"[green]Removed repository: {repo_url}[/green]")
184
+ console.print(removal.summary())
181
185
 
182
186
 
183
187
  @app.command()
@@ -189,6 +193,12 @@ def reindex(
189
193
  autocompletion=complete_repo_by_url,
190
194
  ),
191
195
  ] = None,
196
+ clean: bool = typer.Option(
197
+ False,
198
+ "--clean",
199
+ help="First drop the repo's indexed images and sessions, so every frame is "
200
+ "re-read from disk and its sessions are rebuilt.",
201
+ ),
192
202
  ) -> None:
193
203
  """
194
204
  Reindex a repository by number.
@@ -200,15 +210,20 @@ def reindex(
200
210
  # one in this file is the placeholder from starbash.__init__). The view
201
211
  # must draw on the console the scan's own logging goes to.
202
212
  repo_to_reindex = repo_url_to_repo(sb, repo_url)
213
+ dropped = RepoRemoval()
203
214
 
204
215
  if repo_to_reindex is None:
205
216
  with ReindexView.for_console("Re-indexing repositories", starbash.console):
206
- sb.reindex_repos()
217
+ dropped = sb.reindex_repos(clean=clean)
218
+ if clean:
219
+ console.print(f"Cleared the index before scanning: {dropped.summary()}")
207
220
  else:
208
221
  # Get the repo to reindex
209
222
  console.print(f"Reindexing repository: {repo_to_reindex.url}")
210
223
  with ReindexView.for_console(f"Re-indexing {repo_to_reindex.url}", starbash.console):
211
- sb.reindex_repo(repo_to_reindex)
224
+ dropped = sb.reindex_repo(repo_to_reindex, clean=clean)
225
+ if clean:
226
+ console.print(f"Cleared the index before scanning: {dropped.summary()}")
212
227
  console.print(f"[green]Successfully reindexed repository {repo_to_reindex}[/green]")
213
228
 
214
229
 
@@ -16,6 +16,7 @@ type ImageRow = dict[str, Any]
16
16
 
17
17
  __all__ = [
18
18
  "Database",
19
+ "RepoRemoval",
19
20
  "SearchCondition",
20
21
  "SessionRow",
21
22
  "ImageRow",
@@ -68,6 +69,37 @@ def metadata_to_camera_id(metadata: dict[str, Any]) -> str | None:
68
69
  return camera_id
69
70
 
70
71
 
72
+ @dataclass(frozen=True)
73
+ class RepoRemoval:
74
+ """What :meth:`Database.remove_repo` dropped from the index.
75
+
76
+ Args:
77
+ images: image rows deleted along with the repository.
78
+ sessions: sessions deleted, because every frame they held came from it.
79
+ """
80
+
81
+ images: int = 0
82
+ sessions: int = 0
83
+
84
+ def __add__(self, other: RepoRemoval) -> RepoRemoval:
85
+ """Total two removals, so a multi-repo pass can report one number."""
86
+ return RepoRemoval(
87
+ images=self.images + other.images, sessions=self.sessions + other.sessions
88
+ )
89
+
90
+ def summary(self) -> str:
91
+ """Return a one-line, human readable description of what changed."""
92
+ dropped: list[str] = []
93
+ if self.images:
94
+ dropped.append(f"{self.images} indexed image(s)")
95
+ if self.sessions:
96
+ dropped.append(f"{self.sessions} session(s)")
97
+
98
+ if not dropped:
99
+ return "No indexed files or sessions were affected."
100
+ return "Removed " + " and ".join(dropped) + "."
101
+
102
+
71
103
  class Database:
72
104
  """SQLite-backed application database.
73
105
 
@@ -244,21 +276,19 @@ class Database:
244
276
  self._db.commit()
245
277
 
246
278
  # --- Convenience helpers for common repo operations ---
247
- def remove_repo(self, url: str) -> None:
248
- """Remove a repo record by URL.
279
+ def _drop_repo_index(self, cursor: sqlite3.Cursor, url: str) -> RepoRemoval:
280
+ """Delete a repo's images and the sessions those images built.
249
281
 
250
- This will cascade delete all images belonging to this repo, and all sessions
251
- that reference those images via image_doc_id.
252
-
253
- The relationship is: repos -> images (via repo_id) -> sessions (via image_doc_id).
254
- Sessions have an image_doc_id field that points to a representative image.
255
- We delete sessions whose representative image belongs to the repo being deleted.
282
+ Shared by :meth:`remove_repo` (which then drops the repo row too) and
283
+ :meth:`reset_repo` (which keeps it, so the next scan starts clean).
256
284
 
257
285
  Args:
286
+ cursor: an open cursor on the application database.
258
287
  url: The repository URL (e.g., 'file:///path/to/repo')
259
- """
260
- cursor = self._db.cursor()
261
288
 
289
+ Returns:
290
+ A :class:`RepoRemoval` counting the rows that were dropped.
291
+ """
262
292
  # Use a 3-way join to find and delete sessions that reference images from this repo
263
293
  # repo_url -> repo_id -> images.id -> sessions.image_doc_id
264
294
  cursor.execute(
@@ -274,6 +304,7 @@ class Database:
274
304
  """,
275
305
  (url,),
276
306
  )
307
+ sessions = cursor.rowcount
277
308
 
278
309
  # Delete all images from this repo (using repo_id from URL)
279
310
  cursor.execute(
@@ -283,12 +314,57 @@ class Database:
283
314
  """,
284
315
  (url,),
285
316
  )
317
+ return RepoRemoval(images=cursor.rowcount, sessions=sessions)
318
+
319
+ def reset_repo(self, url: str) -> RepoRemoval:
320
+ """
321
+ Drop everything a repository contributed to the index, keeping the repo.
322
+
323
+ Used before a re-scan (``sb repo reindex --clean``): with the image rows
324
+ gone, every frame the scan meets is a *first* scan, which is the only time
325
+ :meth:`Starbash.add_image_and_session` builds a session for it. A plain
326
+ re-index only refreshes the rows it finds, and never touches the sessions.
327
+
328
+ Args:
329
+ url: The repository URL (e.g., 'file:///path/to/repo')
330
+
331
+ Returns:
332
+ A :class:`RepoRemoval` counting the rows that were dropped.
333
+ """
334
+ cursor = self._db.cursor()
335
+ removal = self._drop_repo_index(cursor, url)
336
+
337
+ self._db.commit()
338
+
339
+ return removal
340
+
341
+ def remove_repo(self, url: str) -> RepoRemoval:
342
+ """Remove a repo record by URL, along with everything it contributed.
343
+
344
+ This cascades to every image belonging to the repo, and to the sessions
345
+ those images built: a session is only ever fed by one repository, so once
346
+ its frames are gone there is nothing left for it to describe.
347
+
348
+ The relationship is: repos -> images (via repo_id) -> sessions (via
349
+ image_doc_id, the representative image a session was built from).
350
+
351
+ Args:
352
+ url: The repository URL (e.g., 'file:///path/to/repo')
353
+
354
+ Returns:
355
+ A :class:`RepoRemoval` counting the rows that were dropped.
356
+ """
357
+ cursor = self._db.cursor()
358
+
359
+ removal = self._drop_repo_index(cursor, url)
286
360
 
287
361
  # Finally delete the repo itself
288
362
  cursor.execute(f"DELETE FROM {self.REPOS_TABLE} WHERE url = ?", (url,))
289
363
 
290
364
  self._db.commit()
291
365
 
366
+ return removal
367
+
292
368
  def upsert_repo(self, url: str) -> int:
293
369
  """Insert or update a repo record by unique URL.
294
370
 
@@ -359,19 +359,19 @@ class ToolAction(BaseAction):
359
359
  if input_files:
360
360
  desc = f"({len(input_files)} input files)"
361
361
 
362
- # Some tools might want us to pre merge all the input frames (siril merge command doesn't nicely work with images
363
- # of different sizes etc).
364
- stage_input: dict[Any, FileInfo] = context["stage_input"]
365
- for fi in stage_input.values():
366
- perhaps_merge_to(fi)
362
+ logging.info(f"Running {self.tool.name} for {self.task.name} {desc}")
363
+ try:
364
+ # Some tools might want us to pre merge all the input frames (siril merge command doesn't nicely work with images
365
+ # of different sizes etc).
366
+ stage_input: dict[Any, FileInfo] = context["stage_input"]
367
+ for fi in stage_input.values():
368
+ perhaps_merge_to(fi)
367
369
 
368
- from starbash.processed_target import ProcessedTarget
370
+ from starbash.processed_target import ProcessedTarget
369
371
 
370
- pt: ProcessedTarget = self.task.meta["processed_target"]
371
- logfile_path = pt.log_path
372
+ pt: ProcessedTarget = self.task.meta["processed_target"]
373
+ logfile_path = pt.log_path
372
374
 
373
- logging.info(f"Running {self.tool.name} for {self.task.name} {desc}")
374
- try:
375
375
  with open(logfile_path, "a", encoding="utf-8") as logfile:
376
376
  self.result = self.tool.run(
377
377
  self.commands, context=context, cwd=self.cwd, log_out=logfile, **self.parameters
@@ -31,7 +31,7 @@ class FilesystemUnavailableError(UserHandledError):
31
31
  def __init__(self, operation: str, cause: OSError) -> None:
32
32
  super().__init__(
33
33
  f"The filesystem became unavailable while {operation}. "
34
- "Check that the drive or network mount is connected, then retry."
34
+ "Check that the drive is connected (and it is not out of space), then retry."
35
35
  )
36
36
  self.cause = cause
37
37